iubenda Cookie Solution for GDPR - Version 2.3.3

Version Description

  • Fix: AddThis purpose category
Download this release

Release Info

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

Code changes from version 2.3.2 to 2.3.3

includes/amp.php CHANGED
@@ -1,399 +1,399 @@
1
- <?php
2
- // exit if accessed directly
3
- if ( ! defined( 'ABSPATH' ) )
4
- exit;
5
-
6
- /**
7
- * iubenda_AMP class.
8
- *
9
- * @class iubenda_AMP
10
- */
11
- class iubenda_AMP {
12
-
13
- /**
14
- * Class constructor.
15
- */
16
- public function __construct() {
17
- // actions
18
- add_action( 'wp_head', array( $this, 'wp_head_amp' ), 100 );
19
- add_action( 'wp_footer', array( $this, 'wp_footer_amp' ), 100 );
20
- add_action( 'amp_post_template_css', array( $this, 'amp_post_template_css' ), 100 );
21
- add_action( 'amp_post_template_footer', array( $this, 'wp_footer_amp' ), 100 );
22
- add_action( 'amp_post_template_footer', array( $this, 'fix_analytics_amp_for_wp' ), 1 );
23
-
24
- // filters
25
- add_filter( 'amp_post_template_data', array( $this, 'amp_post_template_data' ), 100 );
26
- add_filter( 'amp_analytics_entries', array( $this, 'fix_analytics_wp_amp' ), 10 );
27
- }
28
-
29
- /**
30
- * Add scripts and CSS to WP AMP plugin in Transitional mode.
31
- *
32
- * @return mixed
33
- */
34
- public function wp_head_amp() {
35
- if ( iubenda()->options['cs']['amp_support'] === false )
36
- return;
37
-
38
- if ( function_exists( 'is_amp_endpoint' ) && is_amp_endpoint() && ! function_exists( 'ampforwp_is_amp_endpoint' ) ) {
39
- echo '
40
- <script async custom-element="amp-consent" src="https://cdn.ampproject.org/v0/amp-consent-latest.js"></script>
41
- <script async custom-element="amp-iframe" src="https://cdn.ampproject.org/v0/amp-iframe-latest.js"></script>';
42
-
43
- // optional geo support
44
- if ( iubenda()->multilang && ! empty( iubenda()->lang_current ) ) {
45
- $code = iubenda()->options['cs']['code_' . iubenda()->lang_current];
46
- } else {
47
- $code = iubenda()->options['cs']['code_default'];
48
- }
49
-
50
- $configuration_raw = iubenda()->parse_configuration( $code );
51
-
52
- if ( isset( $configuration_raw['gdprAppliesGlobally'] ) && ! $configuration_raw['gdprAppliesGlobally'] ) {
53
- echo '
54
- <script async custom-element="amp-geo" src="https://cdn.ampproject.org/v0/amp-geo-0.1.js"></script>';
55
- }
56
-
57
- // CSS style
58
- echo '
59
- <style amp-custom>
60
- .popupOverlay {
61
- position:fixed;
62
- top: 0;
63
- bottom: 0;
64
- left: 0;
65
- right: 0;
66
- }
67
- amp-iframe {
68
- margin: 0;
69
- }
70
- amp-consent.amp-active {
71
- position:fixed;
72
- top: 0;
73
- bottom: 0;
74
- left: 0;
75
- right: 0;
76
- }
77
- </style>';
78
- }
79
- }
80
-
81
- /**
82
- * Add AMP consent HTML to WP AMP plugin in Transitional mode.
83
- *
84
- * @return mixed
85
- */
86
- public function wp_footer_amp() {
87
- if ( iubenda()->options['cs']['amp_support'] === false )
88
- return;
89
-
90
- if ( function_exists( 'is_amp_endpoint' ) && is_amp_endpoint() || ( function_exists( 'ampforwp_is_amp_endpoint' ) && ampforwp_is_amp_endpoint() ) ) {
91
-
92
- // get code
93
- if ( iubenda()->multilang && ! empty( iubenda()->lang_current ) ) {
94
- $code = iubenda()->options['cs']['code_' . iubenda()->lang_current];
95
- } else {
96
- $code = iubenda()->options['cs']['code_default'];
97
- }
98
-
99
- $configuration = iubenda()->parse_configuration( $code );
100
-
101
- if ( empty( $configuration ) )
102
- return;
103
-
104
- // local file
105
- if ( iubenda()->options['cs']['amp_source'] === 'local' ) {
106
- // multilang support
107
- if ( iubenda()->multilang && ! empty( iubenda()->lang_current ) )
108
- $template_url = $this->get_amp_template_url( iubenda()->lang_current );
109
- else
110
- $template_url = $this->get_amp_template_url();
111
- // remote file
112
- } else {
113
- // multilang support
114
- if ( iubenda()->multilang && ! empty( iubenda()->lang_current ) )
115
- $template_url = esc_url( isset( iubenda()->options['cs']['amp_template'][iubenda()->lang_current] ) ? iubenda()->options['cs']['amp_template'][iubenda()->lang_current] : '' );
116
- else
117
- $template_url = esc_url( iubenda()->options['cs']['amp_template'] );
118
- }
119
-
120
- if ( empty( $template_url ) )
121
- return;
122
-
123
- echo '
124
- <amp-consent id="myUserConsent" layout="nodisplay">
125
- <script type="application/json">
126
- {
127
- "consentInstanceId": "consent' . $configuration['siteId'] . '",
128
- "consentRequired": true,
129
- "promptUI": "myConsentFlow"
130
- }
131
- </script>
132
- <div id="myConsentFlow" class="popupOverlay">
133
- <amp-iframe
134
- layout="fill"
135
- sandbox="allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox"
136
- src="' . esc_url( $template_url ) . '">
137
- <div placeholder>' . __( 'Loading', 'iubenda' ) . '</div>
138
- </amp-iframe>
139
- </div>
140
- </amp-consent>';
141
- }
142
- }
143
-
144
- /**
145
- * Add scripts to AMP for WP plugin and WP AMP plugin in Standard mode.
146
- *
147
- * @return mixed
148
- */
149
- public function amp_post_template_data( $data ) {
150
- if ( iubenda()->options['cs']['amp_support'] === false )
151
- return $data;
152
-
153
- if ( function_exists( 'ampforwp_is_amp_endpoint' ) && ampforwp_is_amp_endpoint() ) {
154
- $data['amp_component_scripts'] = array_merge( $data['amp_component_scripts'],
155
- array( 'amp-consent' => 'https://cdn.ampproject.org/v0/amp-consent-latest.js' )
156
- );
157
- $data['amp_component_scripts'] = array_merge( $data['amp_component_scripts'],
158
- array( 'amp-iframe' => 'https://cdn.ampproject.org/v0/amp-iframe-latest.js' )
159
- );
160
- }
161
-
162
- return $data;
163
- }
164
-
165
- /**
166
- * Add CSS to AMP for WP plugin and WP AMP plugin in Standard mode.
167
- *
168
- * @return mixed
169
- */
170
- public function amp_post_template_css( $data ) {
171
- if ( iubenda()->options['cs']['amp_support'] === false )
172
- return;
173
-
174
- echo '
175
- .popupOverlay {
176
- position:fixed;
177
- top: 0;
178
- bottom: 0;
179
- left: 0;
180
- right: 0;
181
- }
182
- amp-iframe {
183
- margin: 0;
184
- }
185
- amp-consent.amp-active {
186
- position:fixed;
187
- top: 0;
188
- bottom: 0;
189
- left: 0;
190
- right: 0;
191
- }';
192
- }
193
-
194
- /**
195
- * Block analytics in AMP for WP plugin.
196
- *
197
- * @return mixed
198
- */
199
- public function fix_analytics_amp_for_wp( $data ) {
200
- if ( iubenda()->options['cs']['amp_support'] === false )
201
- return $data;
202
-
203
- global $redux_builder_amp;
204
-
205
- if ( $redux_builder_amp == null ) {
206
- $redux_builder_amp = get_option( 'redux_builder_amp', true );
207
- }
208
-
209
- // trick to block the analytics using global $redux_builder_amp variable
210
- if ( ! iubendaParser::consent_given() )
211
- $redux_builder_amp = true;
212
-
213
- return $data;
214
- }
215
-
216
- /**
217
- * Block analytics in WP AMP plugin.
218
- *
219
- * @return mixed
220
- */
221
- public function fix_analytics_wp_amp( $analytics_entries ) {
222
- if ( iubenda()->options['cs']['amp_support'] === false )
223
- return $analytics_entries;
224
-
225
- // block the analytics using the entries filter hook
226
- if ( ! iubendaParser::consent_given() && ! empty( $analytics_entries ) && is_array( $analytics_entries ) ) {
227
- foreach ( $analytics_entries as $id => $entry ) {
228
- $entry['attributes'] = ! empty( $entry['attributes'] ) ? $entry['attributes'] : array();
229
-
230
- $analytics_entries[$id]['attributes'] = array_merge( array( 'data-block-on-consent' => '_till_accepted' ), $entry['attributes'] );
231
- }
232
- }
233
-
234
- return $analytics_entries;
235
- }
236
-
237
- /**
238
- * Prepare HTML iframe template for the AMP.
239
- *
240
- * @return mixed
241
- */
242
- public function prepare_amp_template( $code ) {
243
- $html = '';
244
-
245
- $configuration_raw = iubenda()->parse_configuration( $code );
246
-
247
- if ( ! empty( $configuration_raw ) ) {
248
- // get script
249
- $script_src = ! empty( $configuration_raw['script'] ) ? $configuration_raw['script'] : '//cdn.iubenda.com/cs/iubenda_cs.js';
250
-
251
- // remove from configuration
252
- if ( isset( $configuration_raw['script'] ) )
253
- unset( $configuration_raw['script'] );
254
-
255
- // encode array
256
- $configuration = json_encode( $configuration_raw );
257
-
258
- // remove quotes
259
- $configuration = preg_replace( '/"([a-zA-Z]+[a-zA-Z0-9]*)":/', '$1:', $configuration );
260
- // replace brackets
261
- $configuration = str_replace( array( '{', '}' ), '', $configuration );
262
-
263
- $html .= '<!DOCTYPE html>
264
- <html lang="' . $configuration_raw['lang'] . '">
265
- <head>
266
- <meta charset="UTF-8">
267
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
268
- <meta name="robots" content="noindex">
269
- <meta http-equiv="X-UA-Compatible" content="ie=edge">
270
- <title>' . __( 'AMP Cookie Consent', 'iubenda' ) . '</title>
271
- <script type="text/javascript">
272
- var _iub = _iub || [];
273
- _iub.csConfiguration = {
274
- ';
275
- // print configuration
276
- $html .= $configuration . ',';
277
- $html .= '
278
- banner: {
279
- position: \'float-bottom-center\',
280
- acceptButtonDisplay: true,
281
- customizeButtonDisplay: true,
282
- rejectButtonDisplay: true,
283
- backgroundOverlay: true
284
- },
285
- callback: { // Mandatory
286
- onPreferenceExpressed: function(preference) {
287
- var consentAction = \'reject\';
288
- var consentObject = {
289
- type: \'consent-response\'
290
- };
291
-
292
- if (preference && preference.consent) {
293
- consentAction = \'accept\';
294
- }
295
-
296
- consentObject.action = consentAction;
297
-
298
- if (_iub.cs.options.enableCMP) {
299
- __cmp(\'getConsentData\', null, function(res) {
300
- var consentString = res.consentData;
301
-
302
- if (consentString.length <= 200) {
303
- consentObject.info = consentString;
304
- }
305
-
306
- console.log(\'send consent-response\', consentAction, \'with CMP consent string\', consentString);
307
-
308
- window.parent.postMessage(consentObject, \'*\');
309
- });
310
- }
311
- else {
312
- console.log(\'send consent-response\', consentAction);
313
-
314
- window.parent.postMessage(consentObject, \'*\');
315
- }
316
- }
317
- }
318
- };
319
- </script>
320
- <script async src="' . $script_src . '"></script>
321
- </head>
322
- <body></body>
323
- </html>';
324
- }
325
-
326
- return $html;
327
- }
328
-
329
- /**
330
- * Get local file template url;
331
- *
332
- * @return string
333
- */
334
- public function get_amp_template_url( $template_lang = '' ) {
335
- $template_url = '';
336
- $template_lang = ! empty( $template_lang ) && is_string( $template_lang ) ? $template_lang : '';
337
-
338
- // get basic site host and template file data
339
- $file_url = ! empty( $template_lang ) ? IUBENDA_PLUGIN_URL . '/templates/amp' . '-' . $template_lang . '.html' : IUBENDA_PLUGIN_URL . '/templates/amp.html';
340
- // $file_url = 'https://cdn.iubenda.com/cs/test/cs-for-amp.html'; // debug only
341
- $parsed_site = parse_url( home_url() );
342
- $parsed_file = parse_url( $file_url );
343
- $site_host = $parsed_site['host'] !== 'localhost' ? iubenda()->domain( $parsed_site['host'] ) : 'localhost';
344
- $file_host = $parsed_file['host'] !== 'localhost' ? iubenda()->domain( $parsed_file['host'] ) : 'localhost';
345
- $is_localhost = (bool) ( $site_host == 'localhost' );
346
- $is_subdomain = ! $is_localhost ? (bool) ( $parsed_file['host'] !== $file_host ) : false;
347
-
348
- // check if file host and server host match
349
- // if not, we're good to go
350
- if ( $site_host !== $file_host ) {
351
- $template_url = $file_url;
352
- // if are located on same host do additional tweaks
353
- } else {
354
- // all ok if we're on different subdomains
355
- if ( $parsed_site['host'] !== $parsed_file['host'] )
356
- $template_url = $file_url;
357
- // same hosts, let's tweak the http/https
358
- else {
359
- $has_www = strpos( $parsed_file['host'], 'www.' ) === 0;
360
-
361
- // add or remove www from url string to make iframe url pass AMP validation
362
- $tweaked_host = ! $is_localhost && ( ! $is_subdomain || $has_www ) ? ( ! $has_www ? 'www.' . $parsed_file['host'] : preg_replace( '/^www\./i', '', $parsed_file['host'] ) ) : $parsed_file['host'];
363
-
364
- // generate new url
365
- $tweaked_url = $parsed_file['scheme'] . '://' . $tweaked_host . ( isset( $parsed_file['port'] ) ? ':' . $parsed_file['port'] : '' ) . $parsed_file['path'] . ( ! empty( $parsed_file['query'] ) ? '?' . $parsed_file['query'] : '' );
366
-
367
- // check if file url is valid
368
- if ( $tweaked_url ) {
369
- $template_url = $tweaked_url;
370
- }
371
- }
372
- }
373
-
374
- return $template_url;
375
- }
376
-
377
- /**
378
- * Generate HTML iframe template for the AMP.
379
- *
380
- * @return mixed
381
- */
382
- public function generate_amp_template( $code = '', $lang = '' ) {
383
- if ( empty( $code ) )
384
- return false;
385
-
386
- $template_dir = IUBENDA_PLUGIN_PATH . DIRECTORY_SEPARATOR . 'templates' . DIRECTORY_SEPARATOR;
387
- $template_file = $template_dir . ( ! empty( $lang ) && in_array( $lang, array_keys( iubenda()->languages ) ) ? 'amp' . '-' . $lang . '.html' : 'amp.html' );
388
- $html = $this->prepare_amp_template( $code );
389
-
390
- // bail if the template was not created properly
391
- if ( empty( $html ) )
392
- return false;
393
-
394
- $result = file_put_contents( $template_file, $html );
395
-
396
- return (bool) $result;
397
- }
398
-
399
  }
1
+ <?php
2
+ // exit if accessed directly
3
+ if ( ! defined( 'ABSPATH' ) )
4
+ exit;
5
+
6
+ /**
7
+ * iubenda_AMP class.
8
+ *
9
+ * @class iubenda_AMP
10
+ */
11
+ class iubenda_AMP {
12
+
13
+ /**
14
+ * Class constructor.
15
+ */
16
+ public function __construct() {
17
+ // actions
18
+ add_action( 'wp_head', array( $this, 'wp_head_amp' ), 100 );
19
+ add_action( 'wp_footer', array( $this, 'wp_footer_amp' ), 100 );
20
+ add_action( 'amp_post_template_css', array( $this, 'amp_post_template_css' ), 100 );
21
+ add_action( 'amp_post_template_footer', array( $this, 'wp_footer_amp' ), 100 );
22
+ add_action( 'amp_post_template_footer', array( $this, 'fix_analytics_amp_for_wp' ), 1 );
23
+
24
+ // filters
25
+ add_filter( 'amp_post_template_data', array( $this, 'amp_post_template_data' ), 100 );
26
+ add_filter( 'amp_analytics_entries', array( $this, 'fix_analytics_wp_amp' ), 10 );
27
+ }
28
+
29
+ /**
30
+ * Add scripts and CSS to WP AMP plugin in Transitional mode.
31
+ *
32
+ * @return mixed
33
+ */
34
+ public function wp_head_amp() {
35
+ if ( iubenda()->options['cs']['amp_support'] === false )
36
+ return;
37
+
38
+ if ( function_exists( 'is_amp_endpoint' ) && is_amp_endpoint() && ! function_exists( 'ampforwp_is_amp_endpoint' ) ) {
39
+ echo '
40
+ <script async custom-element="amp-consent" src="https://cdn.ampproject.org/v0/amp-consent-latest.js"></script>
41
+ <script async custom-element="amp-iframe" src="https://cdn.ampproject.org/v0/amp-iframe-latest.js"></script>';
42
+
43
+ // optional geo support
44
+ if ( iubenda()->multilang && ! empty( iubenda()->lang_current ) ) {
45
+ $code = iubenda()->options['cs']['code_' . iubenda()->lang_current];
46
+ } else {
47
+ $code = iubenda()->options['cs']['code_default'];
48
+ }
49
+
50
+ $configuration_raw = iubenda()->parse_configuration( $code );
51
+
52
+ if ( isset( $configuration_raw['gdprAppliesGlobally'] ) && ! $configuration_raw['gdprAppliesGlobally'] ) {
53
+ echo '
54
+ <script async custom-element="amp-geo" src="https://cdn.ampproject.org/v0/amp-geo-0.1.js"></script>';
55
+ }
56
+
57
+ // CSS style
58
+ echo '
59
+ <style amp-custom>
60
+ .popupOverlay {
61
+ position:fixed;
62
+ top: 0;
63
+ bottom: 0;
64
+ left: 0;
65
+ right: 0;
66
+ }
67
+ amp-iframe {
68
+ margin: 0;
69
+ }
70
+ amp-consent.amp-active {
71
+ position:fixed;
72
+ top: 0;
73
+ bottom: 0;
74
+ left: 0;
75
+ right: 0;
76
+ }
77
+ </style>';
78
+ }
79
+ }
80
+
81
+ /**
82
+ * Add AMP consent HTML to WP AMP plugin in Transitional mode.
83
+ *
84
+ * @return mixed
85
+ */
86
+ public function wp_footer_amp() {
87
+ if ( iubenda()->options['cs']['amp_support'] === false )
88
+ return;
89
+
90
+ if ( function_exists( 'is_amp_endpoint' ) && is_amp_endpoint() || ( function_exists( 'ampforwp_is_amp_endpoint' ) && ampforwp_is_amp_endpoint() ) ) {
91
+
92
+ // get code
93
+ if ( iubenda()->multilang && ! empty( iubenda()->lang_current ) ) {
94
+ $code = iubenda()->options['cs']['code_' . iubenda()->lang_current];
95
+ } else {
96
+ $code = iubenda()->options['cs']['code_default'];
97
+ }
98
+
99
+ $configuration = iubenda()->parse_configuration( $code );
100
+
101
+ if ( empty( $configuration ) )
102
+ return;
103
+
104
+ // local file
105
+ if ( iubenda()->options['cs']['amp_source'] === 'local' ) {
106
+ // multilang support
107
+ if ( iubenda()->multilang && ! empty( iubenda()->lang_current ) )
108
+ $template_url = $this->get_amp_template_url( iubenda()->lang_current );
109
+ else
110
+ $template_url = $this->get_amp_template_url();
111
+ // remote file
112
+ } else {
113
+ // multilang support
114
+ if ( iubenda()->multilang && ! empty( iubenda()->lang_current ) )
115
+ $template_url = esc_url( isset( iubenda()->options['cs']['amp_template'][iubenda()->lang_current] ) ? iubenda()->options['cs']['amp_template'][iubenda()->lang_current] : '' );
116
+ else
117
+ $template_url = esc_url( iubenda()->options['cs']['amp_template'] );
118
+ }
119
+
120
+ if ( empty( $template_url ) )
121
+ return;
122
+
123
+ echo '
124
+ <amp-consent id="myUserConsent" layout="nodisplay">
125
+ <script type="application/json">
126
+ {
127
+ "consentInstanceId": "consent' . $configuration['siteId'] . '",
128
+ "consentRequired": true,
129
+ "promptUI": "myConsentFlow"
130
+ }
131
+ </script>
132
+ <div id="myConsentFlow" class="popupOverlay">
133
+ <amp-iframe
134
+ layout="fill"
135
+ sandbox="allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox"
136
+ src="' . esc_url( $template_url ) . '">
137
+ <div placeholder>' . __( 'Loading', 'iubenda' ) . '</div>
138
+ </amp-iframe>
139
+ </div>
140
+ </amp-consent>';
141
+ }
142
+ }
143
+
144
+ /**
145
+ * Add scripts to AMP for WP plugin and WP AMP plugin in Standard mode.
146
+ *
147
+ * @return mixed
148
+ */
149
+ public function amp_post_template_data( $data ) {
150
+ if ( iubenda()->options['cs']['amp_support'] === false )
151
+ return $data;
152
+
153
+ if ( function_exists( 'ampforwp_is_amp_endpoint' ) && ampforwp_is_amp_endpoint() ) {
154
+ $data['amp_component_scripts'] = array_merge( $data['amp_component_scripts'],
155
+ array( 'amp-consent' => 'https://cdn.ampproject.org/v0/amp-consent-latest.js' )
156
+ );
157
+ $data['amp_component_scripts'] = array_merge( $data['amp_component_scripts'],
158
+ array( 'amp-iframe' => 'https://cdn.ampproject.org/v0/amp-iframe-latest.js' )
159
+ );
160
+ }
161
+
162
+ return $data;
163
+ }
164
+
165
+ /**
166
+ * Add CSS to AMP for WP plugin and WP AMP plugin in Standard mode.
167
+ *
168
+ * @return mixed
169
+ */
170
+ public function amp_post_template_css( $data ) {
171
+ if ( iubenda()->options['cs']['amp_support'] === false )
172
+ return;
173
+
174
+ echo '
175
+ .popupOverlay {
176
+ position:fixed;
177
+ top: 0;
178
+ bottom: 0;
179
+ left: 0;
180
+ right: 0;
181
+ }
182
+ amp-iframe {
183
+ margin: 0;
184
+ }
185
+ amp-consent.amp-active {
186
+ position:fixed;
187
+ top: 0;
188
+ bottom: 0;
189
+ left: 0;
190
+ right: 0;
191
+ }';
192
+ }
193
+
194
+ /**
195
+ * Block analytics in AMP for WP plugin.
196
+ *
197
+ * @return mixed
198
+ */
199
+ public function fix_analytics_amp_for_wp( $data ) {
200
+ if ( iubenda()->options['cs']['amp_support'] === false )
201
+ return $data;
202
+
203
+ global $redux_builder_amp;
204
+
205
+ if ( $redux_builder_amp == null ) {
206
+ $redux_builder_amp = get_option( 'redux_builder_amp', true );
207
+ }
208
+
209
+ // trick to block the analytics using global $redux_builder_amp variable
210
+ if ( ! iubendaParser::consent_given() )
211
+ $redux_builder_amp = true;
212
+
213
+ return $data;
214
+ }
215
+
216
+ /**
217
+ * Block analytics in WP AMP plugin.
218
+ *
219
+ * @return mixed
220
+ */
221
+ public function fix_analytics_wp_amp( $analytics_entries ) {
222
+ if ( iubenda()->options['cs']['amp_support'] === false )
223
+ return $analytics_entries;
224
+
225
+ // block the analytics using the entries filter hook
226
+ if ( ! iubendaParser::consent_given() && ! empty( $analytics_entries ) && is_array( $analytics_entries ) ) {
227
+ foreach ( $analytics_entries as $id => $entry ) {
228
+ $entry['attributes'] = ! empty( $entry['attributes'] ) ? $entry['attributes'] : array();
229
+
230
+ $analytics_entries[$id]['attributes'] = array_merge( array( 'data-block-on-consent' => '_till_accepted' ), $entry['attributes'] );
231
+ }
232
+ }
233
+
234
+ return $analytics_entries;
235
+ }
236
+
237
+ /**
238
+ * Prepare HTML iframe template for the AMP.
239
+ *
240
+ * @return mixed
241
+ */
242
+ public function prepare_amp_template( $code ) {
243
+ $html = '';
244
+
245
+ $configuration_raw = iubenda()->parse_configuration( $code );
246
+
247
+ if ( ! empty( $configuration_raw ) ) {
248
+ // get script
249
+ $script_src = ! empty( $configuration_raw['script'] ) ? $configuration_raw['script'] : '//cdn.iubenda.com/cs/iubenda_cs.js';
250
+
251
+ // remove from configuration
252
+ if ( isset( $configuration_raw['script'] ) )
253
+ unset( $configuration_raw['script'] );
254
+
255
+ // encode array
256
+ $configuration = json_encode( $configuration_raw );
257
+
258
+ // remove quotes
259
+ $configuration = preg_replace( '/"([a-zA-Z]+[a-zA-Z0-9]*)":/', '$1:', $configuration );
260
+ // replace brackets
261
+ $configuration = str_replace( array( '{', '}' ), '', $configuration );
262
+
263
+ $html .= '<!DOCTYPE html>
264
+ <html lang="' . $configuration_raw['lang'] . '">
265
+ <head>
266
+ <meta charset="UTF-8">
267
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
268
+ <meta name="robots" content="noindex">
269
+ <meta http-equiv="X-UA-Compatible" content="ie=edge">
270
+ <title>' . __( 'AMP Cookie Consent', 'iubenda' ) . '</title>
271
+ <script type="text/javascript">
272
+ var _iub = _iub || [];
273
+ _iub.csConfiguration = {
274
+ ';
275
+ // print configuration
276
+ $html .= $configuration . ',';
277
+ $html .= '
278
+ banner: {
279
+ position: \'float-bottom-center\',
280
+ acceptButtonDisplay: true,
281
+ customizeButtonDisplay: true,
282
+ rejectButtonDisplay: true,
283
+ backgroundOverlay: true
284
+ },
285
+ callback: { // Mandatory
286
+ onPreferenceExpressed: function(preference) {
287
+ var consentAction = \'reject\';
288
+ var consentObject = {
289
+ type: \'consent-response\'
290
+ };
291
+
292
+ if (preference && preference.consent) {
293
+ consentAction = \'accept\';
294
+ }
295
+
296
+ consentObject.action = consentAction;
297
+
298
+ if (_iub.cs.options.enableCMP) {
299
+ __cmp(\'getConsentData\', null, function(res) {
300
+ var consentString = res.consentData;
301
+
302
+ if (consentString.length <= 200) {
303
+ consentObject.info = consentString;
304
+ }
305
+
306
+ console.log(\'send consent-response\', consentAction, \'with CMP consent string\', consentString);
307
+
308
+ window.parent.postMessage(consentObject, \'*\');
309
+ });
310
+ }
311
+ else {
312
+ console.log(\'send consent-response\', consentAction);
313
+
314
+ window.parent.postMessage(consentObject, \'*\');
315
+ }
316
+ }
317
+ }
318
+ };
319
+ </script>
320
+ <script async src="' . $script_src . '"></script>
321
+ </head>
322
+ <body></body>
323
+ </html>';
324
+ }
325
+
326
+ return $html;
327
+ }
328
+
329
+ /**
330
+ * Get local file template url;
331
+ *
332
+ * @return string
333
+ */
334
+ public function get_amp_template_url( $template_lang = '' ) {
335
+ $template_url = '';
336
+ $template_lang = ! empty( $template_lang ) && is_string( $template_lang ) ? $template_lang : '';
337
+
338
+ // get basic site host and template file data
339
+ $file_url = ! empty( $template_lang ) ? IUBENDA_PLUGIN_URL . '/templates/amp' . '-' . $template_lang . '.html' : IUBENDA_PLUGIN_URL . '/templates/amp.html';
340
+ // $file_url = 'https://cdn.iubenda.com/cs/test/cs-for-amp.html'; // debug only
341
+ $parsed_site = parse_url( home_url() );
342
+ $parsed_file = parse_url( $file_url );
343
+ $site_host = $parsed_site['host'] !== 'localhost' ? iubenda()->domain( $parsed_site['host'] ) : 'localhost';
344
+ $file_host = $parsed_file['host'] !== 'localhost' ? iubenda()->domain( $parsed_file['host'] ) : 'localhost';
345
+ $is_localhost = (bool) ( $site_host == 'localhost' );
346
+ $is_subdomain = ! $is_localhost ? (bool) ( $parsed_file['host'] !== $file_host ) : false;
347
+
348
+ // check if file host and server host match
349
+ // if not, we're good to go
350
+ if ( $site_host !== $file_host ) {
351
+ $template_url = $file_url;
352
+ // if are located on same host do additional tweaks
353
+ } else {
354
+ // all ok if we're on different subdomains
355
+ if ( $parsed_site['host'] !== $parsed_file['host'] )
356
+ $template_url = $file_url;
357
+ // same hosts, let's tweak the http/https
358
+ else {
359
+ $has_www = strpos( $parsed_file['host'], 'www.' ) === 0;
360
+
361
+ // add or remove www from url string to make iframe url pass AMP validation
362
+ $tweaked_host = ! $is_localhost && ( ! $is_subdomain || $has_www ) ? ( ! $has_www ? 'www.' . $parsed_file['host'] : preg_replace( '/^www\./i', '', $parsed_file['host'] ) ) : $parsed_file['host'];
363
+
364
+ // generate new url
365
+ $tweaked_url = $parsed_file['scheme'] . '://' . $tweaked_host . ( isset( $parsed_file['port'] ) ? ':' . $parsed_file['port'] : '' ) . $parsed_file['path'] . ( ! empty( $parsed_file['query'] ) ? '?' . $parsed_file['query'] : '' );
366
+
367
+ // check if file url is valid
368
+ if ( $tweaked_url ) {
369
+ $template_url = $tweaked_url;
370
+ }
371
+ }
372
+ }
373
+
374
+ return $template_url;
375
+ }
376
+
377
+ /**
378
+ * Generate HTML iframe template for the AMP.
379
+ *
380
+ * @return mixed
381
+ */
382
+ public function generate_amp_template( $code = '', $lang = '' ) {
383
+ if ( empty( $code ) )
384
+ return false;
385
+
386
+ $template_dir = IUBENDA_PLUGIN_PATH . DIRECTORY_SEPARATOR . 'templates' . DIRECTORY_SEPARATOR;
387
+ $template_file = $template_dir . ( ! empty( $lang ) && in_array( $lang, array_keys( iubenda()->languages ) ) ? 'amp' . '-' . $lang . '.html' : 'amp.html' );
388
+ $html = $this->prepare_amp_template( $code );
389
+
390
+ // bail if the template was not created properly
391
+ if ( empty( $html ) )
392
+ return false;
393
+
394
+ $result = file_put_contents( $template_file, $html );
395
+
396
+ return (bool) $result;
397
+ }
398
+
399
  }
includes/forms-list-table.php CHANGED
@@ -1,367 +1,367 @@
1
- <?php
2
- // exit if accessed directly
3
- if ( ! defined( 'ABSPATH' ) )
4
- exit;
5
-
6
- /**
7
- * iubenda_List_Table_Forms class.
8
- *
9
- * @class iubenda_List_Table_Forms
10
- */
11
- class iubenda_List_Table_Forms extends WP_List_Table {
12
-
13
- public $items;
14
- public $extra_items;
15
- public $base_url;
16
-
17
- /**
18
- * Class constructor.
19
- */
20
- public function __construct() {
21
- global $status, $page;
22
-
23
- // set parent defaults
24
- parent::__construct( array(
25
- 'ajax' => false
26
- ) );
27
-
28
- $this->base_url = esc_url_raw( add_query_arg( array( 'tab' => 'cons' ), iubenda()->base_url ) );
29
- }
30
-
31
-
32
-
33
- /**
34
- * Prepare the items for the table to process.
35
- */
36
- public function prepare_items() {
37
- if ( ! empty( $_GET['status'] ) && array_key_exists( $_GET['status'], iubenda()->forms->statuses ) )
38
- $status = $_GET['status'];
39
- else
40
- $status = '';
41
-
42
- $orderby = ( isset( $_GET['orderby'] ) ) ? esc_attr( $_GET['orderby'] ) : 'date';
43
- $order = ( isset( $_GET['order'] ) ) && in_array( $_GET['order'], array( 'asc', 'desc' ) ) ? esc_attr( $_GET['order'] ) : 'desc';
44
-
45
- $per_page = 20;
46
-
47
- if ( isset( $_GET['number'] ) ) {
48
- $number = (int) $_GET['number'];
49
- } else {
50
- $number = $per_page + min( 8, $per_page ); // grab a few extra
51
- }
52
- $page = $this->get_pagenum();
53
-
54
- $args = array(
55
- 'orderby' => $orderby,
56
- 'order' => $order,
57
- 'offset' => 0,
58
- 'number' => 0,
59
- 'post_status' => $status
60
- );
61
-
62
- $items = iubenda()->forms->get_forms( $args );
63
-
64
- // echo '<pre>'; print_r( $items ); echo '</pre>';
65
-
66
- if ( is_array( $items ) ) {
67
- $this->items = array_slice( $items, 0, $per_page );
68
- $this->extra_items = array_slice( $items, $per_page );
69
- }
70
-
71
- // echo '<pre>'; print_r( $this->extra_items ); echo '</pre>';
72
-
73
- $this->set_pagination_args( array(
74
- 'total_items' => count( $items ),
75
- 'per_page' => $per_page,
76
- ) );
77
-
78
- $columns = $this->get_columns();
79
- $hidden = array();
80
- $sortable = $this->get_sortable_columns();
81
- $this->_column_headers = array( $columns, $hidden, $sortable );
82
- }
83
-
84
- /**
85
- * Override the parent columns method. Defines the columns to use in your listing table.
86
- *
87
- * @return array
88
- */
89
- public function get_columns() {
90
- $columns = array(
91
- 'cb' => '<input type="checkbox"/>',
92
- 'title' => __( 'Form Title', 'iubenda' ),
93
- 'ID' => __( 'Form ID', 'iubenda' ),
94
- 'source' => __( 'Form Source', 'iubenda' ),
95
- 'fields' => __( 'Fields', 'iubenda' ),
96
- 'date' => __( 'Date', 'iubenda' ),
97
- );
98
-
99
- return $columns;
100
- }
101
-
102
- /**
103
- * Define the sortable columns.
104
- *
105
- * @return array
106
- */
107
- public function get_sortable_columns() {
108
- $columns = array(
109
- 'title' => array( 'name', true )
110
- );
111
- return $columns;
112
- }
113
-
114
- /**
115
- * Handle single row content.
116
- *
117
- * @param array $item
118
- * @return mixed
119
- */
120
- public function single_row( $item ) {
121
- $classes = array();
122
- $classes[] = 'item-' . $item->ID;
123
- ?>
124
- <tr id="item-<?php echo $item->ID; ?>" class="<?php echo implode( ' ', $classes ); ?>">
125
- <?php $this->single_row_columns( $item ); ?>
126
- </tr>
127
- <?php
128
- }
129
-
130
- /**
131
- * Get the name of the default primary column.
132
- *
133
- * @return string Name of the default primary column, in this case, 'title'.
134
- */
135
- public function get_default_primary_column_name() {
136
- return 'title';
137
- }
138
-
139
- /**
140
- * Generate and display row actions links.
141
- *
142
- * @param object $item
143
- * @param string $column_name
144
- * @param string $primary
145
- * @return string|void
146
- */
147
- public function handle_row_actions( $item, $column_name, $primary ) {
148
- if ( $column_name !== 'title' ) {
149
- return '';
150
- }
151
-
152
- $output = '';
153
-
154
- $del_nonce = esc_html( '_wpnonce=' . wp_create_nonce( "delete-form_{$item->ID}" ) );
155
- $url = add_query_arg( array( 'form_id' => $item->ID ), $this->base_url );
156
- $edit_url = add_query_arg( array( 'action' => 'edit' ), $url );
157
- $delete_url = add_query_arg( array( 'action' => 'delete' ), $url ) . "&$del_nonce";
158
-
159
- // preorder it: View | Approve | Unapprove | Delete
160
- $actions = array(
161
- 'view' => '',
162
- 'delete' => ''
163
- );
164
-
165
- $actions['view'] = "<a href='$edit_url' aria-label='" . esc_attr__( 'Edit this form', 'iubenda' ) . "'>" . __( 'Edit' ) . '</a>';
166
- $actions['delete'] = "<a href='$delete_url' aria-label='" . esc_attr__( 'Delete this form', 'iubenda' ) . "'>" . __( 'Delete', 'iubenda' ) . '</a>';
167
-
168
- $i = 0;
169
- $output .= '<div class="row-actions">';
170
- foreach ( $actions as $action => $link ) {
171
- ++ $i;
172
- $sep = ( 1 === $i ) ? $sep = '' : $sep = ' | ';
173
- $output .= '<span class="' . ( $action === 'delete' ? 'delete delete-form' : $action ) . '">' . $sep . $link . '</span>';
174
- }
175
- $output .= '</div>';
176
-
177
- return $output;
178
- }
179
-
180
- /**
181
- * Define what data to show on each column of the table.
182
- *
183
- * @param array $item
184
- * @param string $column_name
185
- * @return mixed
186
- */
187
- public function column_default( $item, $column_name ) {
188
- $output = '';
189
-
190
- if ( ! empty( $_GET['status'] ) && array_key_exists( $_GET['status'], iubenda()->forms->statuses ) )
191
- $status = $_GET['status'];
192
- else
193
- $status = '';
194
-
195
- // print_r( $item );
196
-
197
- // get columns content
198
- switch ( $column_name ) {
199
- case 'ID':
200
- $output = $item->ID;
201
- break;
202
- case 'title':
203
- $output = '<strong>' . ( current_user_can( 'edit_post', $item->ID ) ? '<a href="' . esc_url_raw( add_query_arg( array( 'form_id' => $item->ID, 'action' => 'edit' ), $this->base_url ) ) . '">' . $item->post_title . '</a>' : $item->post_title );
204
-
205
- if ( ! $status ) {
206
- if ( in_array( $item->post_status, array( 'publish', 'needs_update' ) ) ) {
207
- $output .= ' &mdash; ';
208
- $output .= '<span class="post-state to-map-state">' . iubenda()->forms->statuses[$item->post_status] . '</span>';
209
- }
210
- }
211
-
212
- $output .= '</strong>';
213
-
214
- break;
215
- case 'source':
216
- $output = array_key_exists( $item->form_source, iubenda()->forms->sources ) ? iubenda()->forms->sources[$item->form_source] : '&#8212;';
217
- break;
218
- case 'fields':
219
- $output = count( $item->form_fields );
220
- break;
221
- case 'date':
222
- $output = date_i18n( $item->post_date );
223
- break;
224
- default:
225
- break;
226
- }
227
-
228
- return $output;
229
- }
230
-
231
- /**
232
- * Display checkboxex callback.
233
- *
234
- * @return string
235
- */
236
- public function column_cb( $item ) {
237
- return sprintf(
238
- '<input type="checkbox" name="%1$s[]" value="%2$s" />', 'form', $item->ID
239
- );
240
- }
241
-
242
- /**
243
- * Generate the table navigation above or below the table
244
- *
245
- * @since 3.1.0
246
- * @param string $which
247
- */
248
- protected function display_tablenav( $which ) {
249
- ?>
250
- <div class="tablenav <?php echo esc_attr( $which ); ?>">
251
- <?php
252
- // $this->extra_tablenav( $which );
253
- $this->pagination( $which );
254
- ?>
255
-
256
- <br class="clear" />
257
- </div>
258
- <?php
259
- }
260
-
261
- /**
262
- * @param string $which
263
- */
264
- protected function extra_tablenav( $which ) {
265
- ?>
266
- <div class="alignleft actions">
267
- <?php
268
- if ( 'top' === $which ) {
269
- ob_start();
270
-
271
- $this->sources_dropdown();
272
-
273
- $output = ob_get_clean();
274
-
275
- if ( ! empty( $output ) ) {
276
- echo $output;
277
- submit_button( __( 'Filter' ), '', 'filter_action', false, array( 'id' => 'post-query-submit' ) );
278
- }
279
- }
280
- ?>
281
- </div>
282
- <?php
283
- }
284
-
285
- /**
286
- * Displays a sources drop-down for filtering on the list table.
287
- *
288
- * @return mixed
289
- */
290
- protected function sources_dropdown() {
291
- if ( ! empty( iubenda()->forms->sources ) ) {
292
- $current = ! empty( $_GET['source'] ) && in_array( $_GET['source'], iubenda()->forms->sources ) ? esc_attr( $_GET['source'] ) : '';
293
- echo '
294
- <label class="screen-reader-text" for="cat">' . __( 'Filter by source', 'iubenda' ) . '</label>
295
- <select name="source" id="filter-by-source">
296
- <option ' . selected( '', $current, false ) . 'value="">' . __( 'All form sources', 'iubenda' ) . '</option>';
297
- foreach ( iubenda()->forms->sources as $key => $label ) {
298
- echo '
299
- <option ' . selected( $key, $current, false ) . 'value="' . $key . '">' . $label . '</option>';
300
- }
301
-
302
- echo '</select>';
303
- }
304
- }
305
-
306
- /**
307
- * Display views.
308
- *
309
- * @return array
310
- */
311
- public function get_views() {
312
- if ( ! empty( $_GET['status'] ) && array_key_exists( $_GET['status'], iubenda()->forms->statuses ) )
313
- $status = $_GET['status'];
314
- else
315
- $status = '';
316
-
317
- $orderby = ( isset( $_GET['orderby'] ) ) ? esc_attr( $_GET['orderby'] ) : '';
318
- $order = ( isset( $_GET['order'] ) ) ? esc_attr( $_GET['order'] ) : '';
319
-
320
- $per_page = 20;
321
-
322
- if ( isset( $_GET['number'] ) ) {
323
- $number = (int) $_GET['number'];
324
- } else {
325
- $number = $per_page + min( 8, $per_page ); // grab a few extra
326
- }
327
- $page = $this->get_pagenum();
328
- $items_total = 0;
329
-
330
- $args = array(
331
- 'orderby' => $orderby,
332
- 'order' => $order,
333
- 'offset' => 0,
334
- 'number' => 0
335
- );
336
-
337
- foreach ( iubenda()->forms->statuses as $key => $view ) {
338
- $args['post_status'] = $key;
339
-
340
- $items = iubenda()->forms->get_forms( $args );
341
-
342
- $items_count[$key] = count( $items );
343
- $items_total = $items_total + $items_count[$key];
344
- }
345
-
346
- $views = $items_total > 0 ? array(
347
- 'all' => '<a href="' . $this->base_url . '"' . ($status === '' ? ' class="current"' : '') . '>' . esc_html__( 'All' ) . ' <span class="count">(' . $items_total . ')</span></a>'
348
- ) : '';
349
-
350
- foreach ( iubenda()->forms->statuses as $key => $view ) {
351
- if ( (int) $items_count[$key] > 0 )
352
- $views[$key] = '<a href="' . esc_url_raw( add_query_arg( array( 'status' => $key ), $this->base_url ) ) . '" ' . ($status === $key ? ' class="current"' : '') . '>' . sprintf( _n( '%1$s <span class="count">(%2$s)</span>', '%1$s <span class="count">(%2$s)</span>', $items_count[$key], 'iubenda' ), $view, $items_count[$key] ) . '</a>';
353
- }
354
-
355
- return $views;
356
- }
357
-
358
- /**
359
- * Display empty result.
360
- *
361
- * @return string
362
- */
363
- public function no_items() {
364
- echo __( 'No forms found.', 'iubenda' );
365
- }
366
-
367
  }
1
+ <?php
2
+ // exit if accessed directly
3
+ if ( ! defined( 'ABSPATH' ) )
4
+ exit;
5
+
6
+ /**
7
+ * iubenda_List_Table_Forms class.
8
+ *
9
+ * @class iubenda_List_Table_Forms
10
+ */
11
+ class iubenda_List_Table_Forms extends WP_List_Table {
12
+
13
+ public $items;
14
+ public $extra_items;
15
+ public $base_url;
16
+
17
+ /**
18
+ * Class constructor.
19
+ */
20
+ public function __construct() {
21
+ global $status, $page;
22
+
23
+ // set parent defaults
24
+ parent::__construct( array(
25
+ 'ajax' => false
26
+ ) );
27
+
28
+ $this->base_url = esc_url_raw( add_query_arg( array( 'tab' => 'cons' ), iubenda()->base_url ) );
29
+ }
30
+
31
+
32
+
33
+ /**
34
+ * Prepare the items for the table to process.
35
+ */
36
+ public function prepare_items() {
37
+ if ( ! empty( $_GET['status'] ) && array_key_exists( $_GET['status'], iubenda()->forms->statuses ) )
38
+ $status = $_GET['status'];
39
+ else
40
+ $status = '';
41
+
42
+ $orderby = ( isset( $_GET['orderby'] ) ) ? esc_attr( $_GET['orderby'] ) : 'date';
43
+ $order = ( isset( $_GET['order'] ) ) && in_array( $_GET['order'], array( 'asc', 'desc' ) ) ? esc_attr( $_GET['order'] ) : 'desc';
44
+
45
+ $per_page = 20;
46
+
47
+ if ( isset( $_GET['number'] ) ) {
48
+ $number = (int) $_GET['number'];
49
+ } else {
50
+ $number = $per_page + min( 8, $per_page ); // grab a few extra
51
+ }
52
+ $page = $this->get_pagenum();
53
+
54
+ $args = array(
55
+ 'orderby' => $orderby,
56
+ 'order' => $order,
57
+ 'offset' => 0,
58
+ 'number' => 0,
59
+ 'post_status' => $status
60
+ );
61
+
62
+ $items = iubenda()->forms->get_forms( $args );
63
+
64
+ // echo '<pre>'; print_r( $items ); echo '</pre>';
65
+
66
+ if ( is_array( $items ) ) {
67
+ $this->items = array_slice( $items, 0, $per_page );
68
+ $this->extra_items = array_slice( $items, $per_page );
69
+ }
70
+
71
+ // echo '<pre>'; print_r( $this->extra_items ); echo '</pre>';
72
+
73
+ $this->set_pagination_args( array(
74
+ 'total_items' => count( $items ),
75
+ 'per_page' => $per_page,
76
+ ) );
77
+
78
+ $columns = $this->get_columns();
79
+ $hidden = array();
80
+ $sortable = $this->get_sortable_columns();
81
+ $this->_column_headers = array( $columns, $hidden, $sortable );
82
+ }
83
+
84
+ /**
85
+ * Override the parent columns method. Defines the columns to use in your listing table.
86
+ *
87
+ * @return array
88
+ */
89
+ public function get_columns() {
90
+ $columns = array(
91
+ 'cb' => '<input type="checkbox"/>',
92
+ 'title' => __( 'Form Title', 'iubenda' ),
93
+ 'ID' => __( 'Form ID', 'iubenda' ),
94
+ 'source' => __( 'Form Source', 'iubenda' ),
95
+ 'fields' => __( 'Fields', 'iubenda' ),
96
+ 'date' => __( 'Date', 'iubenda' ),
97
+ );
98
+
99
+ return $columns;
100
+ }
101
+
102
+ /**
103
+ * Define the sortable columns.
104
+ *
105
+ * @return array
106
+ */
107
+ public function get_sortable_columns() {
108
+ $columns = array(
109
+ 'title' => array( 'name', true )
110
+ );
111
+ return $columns;
112
+ }
113
+
114
+ /**
115
+ * Handle single row content.
116
+ *
117
+ * @param array $item
118
+ * @return mixed
119
+ */
120
+ public function single_row( $item ) {
121
+ $classes = array();
122
+ $classes[] = 'item-' . $item->ID;
123
+ ?>
124
+ <tr id="item-<?php echo $item->ID; ?>" class="<?php echo implode( ' ', $classes ); ?>">
125
+ <?php $this->single_row_columns( $item ); ?>
126
+ </tr>
127
+ <?php
128
+ }
129
+
130
+ /**
131
+ * Get the name of the default primary column.
132
+ *
133
+ * @return string Name of the default primary column, in this case, 'title'.
134
+ */
135
+ public function get_default_primary_column_name() {
136
+ return 'title';
137
+ }
138
+
139
+ /**
140
+ * Generate and display row actions links.
141
+ *
142
+ * @param object $item
143
+ * @param string $column_name
144
+ * @param string $primary
145
+ * @return string|void
146
+ */
147
+ public function handle_row_actions( $item, $column_name, $primary ) {
148
+ if ( $column_name !== 'title' ) {
149
+ return '';
150
+ }
151
+
152
+ $output = '';
153
+
154
+ $del_nonce = esc_html( '_wpnonce=' . wp_create_nonce( "delete-form_{$item->ID}" ) );
155
+ $url = add_query_arg( array( 'form_id' => $item->ID ), $this->base_url );
156
+ $edit_url = add_query_arg( array( 'action' => 'edit' ), $url );
157
+ $delete_url = add_query_arg( array( 'action' => 'delete' ), $url ) . "&$del_nonce";
158
+
159
+ // preorder it: View | Approve | Unapprove | Delete
160
+ $actions = array(
161
+ 'view' => '',
162
+ 'delete' => ''
163
+ );
164
+
165
+ $actions['view'] = "<a href='$edit_url' aria-label='" . esc_attr__( 'Edit this form', 'iubenda' ) . "'>" . __( 'Edit' ) . '</a>';
166
+ $actions['delete'] = "<a href='$delete_url' aria-label='" . esc_attr__( 'Delete this form', 'iubenda' ) . "'>" . __( 'Delete', 'iubenda' ) . '</a>';
167
+
168
+ $i = 0;
169
+ $output .= '<div class="row-actions">';
170
+ foreach ( $actions as $action => $link ) {
171
+ ++ $i;
172
+ $sep = ( 1 === $i ) ? $sep = '' : $sep = ' | ';
173
+ $output .= '<span class="' . ( $action === 'delete' ? 'delete delete-form' : $action ) . '">' . $sep . $link . '</span>';
174
+ }
175
+ $output .= '</div>';
176
+
177
+ return $output;
178
+ }
179
+
180
+ /**
181
+ * Define what data to show on each column of the table.
182
+ *
183
+ * @param array $item
184
+ * @param string $column_name
185
+ * @return mixed
186
+ */
187
+ public function column_default( $item, $column_name ) {
188
+ $output = '';
189
+
190
+ if ( ! empty( $_GET['status'] ) && array_key_exists( $_GET['status'], iubenda()->forms->statuses ) )
191
+ $status = $_GET['status'];
192
+ else
193
+ $status = '';
194
+
195
+ // print_r( $item );
196
+
197
+ // get columns content
198
+ switch ( $column_name ) {
199
+ case 'ID':
200
+ $output = $item->ID;
201
+ break;
202
+ case 'title':
203
+ $output = '<strong>' . ( current_user_can( 'edit_post', $item->ID ) ? '<a href="' . esc_url_raw( add_query_arg( array( 'form_id' => $item->ID, 'action' => 'edit' ), $this->base_url ) ) . '">' . $item->post_title . '</a>' : $item->post_title );
204
+
205
+ if ( ! $status ) {
206
+ if ( in_array( $item->post_status, array( 'publish', 'needs_update' ) ) ) {
207
+ $output .= ' &mdash; ';
208
+ $output .= '<span class="post-state to-map-state">' . iubenda()->forms->statuses[$item->post_status] . '</span>';
209
+ }
210
+ }
211
+
212
+ $output .= '</strong>';
213
+
214
+ break;
215
+ case 'source':
216
+ $output = array_key_exists( $item->form_source, iubenda()->forms->sources ) ? iubenda()->forms->sources[$item->form_source] : '&#8212;';
217
+ break;
218
+ case 'fields':
219
+ $output = count( $item->form_fields );
220
+ break;
221
+ case 'date':
222
+ $output = date_i18n( $item->post_date );
223
+ break;
224
+ default:
225
+ break;
226
+ }
227
+
228
+ return $output;
229
+ }
230
+
231
+ /**
232
+ * Display checkboxex callback.
233
+ *
234
+ * @return string
235
+ */
236
+ public function column_cb( $item ) {
237
+ return sprintf(
238
+ '<input type="checkbox" name="%1$s[]" value="%2$s" />', 'form', $item->ID
239
+ );
240
+ }
241
+
242
+ /**
243
+ * Generate the table navigation above or below the table
244
+ *
245
+ * @since 3.1.0
246
+ * @param string $which
247
+ */
248
+ protected function display_tablenav( $which ) {
249
+ ?>
250
+ <div class="tablenav <?php echo esc_attr( $which ); ?>">
251
+ <?php
252
+ // $this->extra_tablenav( $which );
253
+ $this->pagination( $which );
254
+ ?>
255
+
256
+ <br class="clear" />
257
+ </div>
258
+ <?php
259
+ }
260
+
261
+ /**
262
+ * @param string $which
263
+ */
264
+ protected function extra_tablenav( $which ) {
265
+ ?>
266
+ <div class="alignleft actions">
267
+ <?php
268
+ if ( 'top' === $which ) {
269
+ ob_start();
270
+
271
+ $this->sources_dropdown();
272
+
273
+ $output = ob_get_clean();
274
+
275
+ if ( ! empty( $output ) ) {
276
+ echo $output;
277
+ submit_button( __( 'Filter' ), '', 'filter_action', false, array( 'id' => 'post-query-submit' ) );
278
+ }
279
+ }
280
+ ?>
281
+ </div>
282
+ <?php
283
+ }
284
+
285
+ /**
286
+ * Displays a sources drop-down for filtering on the list table.
287
+ *
288
+ * @return mixed
289
+ */
290
+ protected function sources_dropdown() {
291
+ if ( ! empty( iubenda()->forms->sources ) ) {
292
+ $current = ! empty( $_GET['source'] ) && in_array( $_GET['source'], iubenda()->forms->sources ) ? esc_attr( $_GET['source'] ) : '';
293
+ echo '
294
+ <label class="screen-reader-text" for="cat">' . __( 'Filter by source', 'iubenda' ) . '</label>
295
+ <select name="source" id="filter-by-source">
296
+ <option ' . selected( '', $current, false ) . 'value="">' . __( 'All form sources', 'iubenda' ) . '</option>';
297
+ foreach ( iubenda()->forms->sources as $key => $label ) {
298
+ echo '
299
+ <option ' . selected( $key, $current, false ) . 'value="' . $key . '">' . $label . '</option>';
300
+ }
301
+
302
+ echo '</select>';
303
+ }
304
+ }
305
+
306
+ /**
307
+ * Display views.
308
+ *
309
+ * @return array
310
+ */
311
+ public function get_views() {
312
+ if ( ! empty( $_GET['status'] ) && array_key_exists( $_GET['status'], iubenda()->forms->statuses ) )
313
+ $status = $_GET['status'];
314
+ else
315
+ $status = '';
316
+
317
+ $orderby = ( isset( $_GET['orderby'] ) ) ? esc_attr( $_GET['orderby'] ) : '';
318
+ $order = ( isset( $_GET['order'] ) ) ? esc_attr( $_GET['order'] ) : '';
319
+
320
+ $per_page = 20;
321
+
322
+ if ( isset( $_GET['number'] ) ) {
323
+ $number = (int) $_GET['number'];
324
+ } else {
325
+ $number = $per_page + min( 8, $per_page ); // grab a few extra
326
+ }
327
+ $page = $this->get_pagenum();
328
+ $items_total = 0;
329
+
330
+ $args = array(
331
+ 'orderby' => $orderby,
332
+ 'order' => $order,
333
+ 'offset' => 0,
334
+ 'number' => 0
335
+ );
336
+
337
+ foreach ( iubenda()->forms->statuses as $key => $view ) {
338
+ $args['post_status'] = $key;
339
+
340
+ $items = iubenda()->forms->get_forms( $args );
341
+
342
+ $items_count[$key] = count( $items );
343
+ $items_total = $items_total + $items_count[$key];
344
+ }
345
+
346
+ $views = $items_total > 0 ? array(
347
+ 'all' => '<a href="' . $this->base_url . '"' . ($status === '' ? ' class="current"' : '') . '>' . esc_html__( 'All' ) . ' <span class="count">(' . $items_total . ')</span></a>'
348
+ ) : '';
349
+
350
+ foreach ( iubenda()->forms->statuses as $key => $view ) {
351
+ if ( (int) $items_count[$key] > 0 )
352
+ $views[$key] = '<a href="' . esc_url_raw( add_query_arg( array( 'status' => $key ), $this->base_url ) ) . '" ' . ($status === $key ? ' class="current"' : '') . '>' . sprintf( _n( '%1$s <span class="count">(%2$s)</span>', '%1$s <span class="count">(%2$s)</span>', $items_count[$key], 'iubenda' ), $view, $items_count[$key] ) . '</a>';
353
+ }
354
+
355
+ return $views;
356
+ }
357
+
358
+ /**
359
+ * Display empty result.
360
+ *
361
+ * @return string
362
+ */
363
+ public function no_items() {
364
+ echo __( 'No forms found.', 'iubenda' );
365
+ }
366
+
367
  }
includes/forms.php CHANGED
@@ -1,969 +1,969 @@
1
- <?php
2
- // exit if accessed directly
3
- if ( ! defined( 'ABSPATH' ) )
4
- exit;
5
-
6
- /**
7
- * iubenda_Forms class.
8
- *
9
- * @class iubenda_Forms
10
- */
11
- class iubenda_Forms {
12
-
13
- public $sources = array();
14
- public $statuses = array();
15
-
16
- /**
17
- * Class constructor.
18
- */
19
- public function __construct() {
20
- // actions
21
- add_action( 'plugins_loaded', array( $this, 'init' ) );
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
- /**
28
- * Initialize forms data.
29
- *
30
- * @return void
31
- */
32
- public function init() {
33
- // WOrdPress commenting form
34
- $this->sources['wp_comment_form'] = 'WordPress Comment';
35
-
36
- // check if Contact Form 7 is active
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';
49
- }
50
-
51
- $this->sources = apply_filters( 'iub_supported_form_sources', $this->sources );
52
-
53
- $this->statuses = array(
54
- 'publish' => _x( 'To Map', 'post status', 'iubenda' ),
55
- 'mapped' => _x( 'Mapped', 'post status', 'iubenda' ),
56
- 'needs_update' => _x( 'Needs Update', 'post status', 'iubenda' ),
57
- // 'trash' => _x( 'Ignored', 'post status', 'iubenda' )
58
- );
59
- }
60
-
61
- /**
62
- * Enqueue frontend script.
63
- */
64
- public function wp_enqueue_scripts() {
65
- if ( ! empty( iubenda()->options['cons']['public_api_key'] ) ) {
66
- wp_register_script( 'iubenda-forms', IUBENDA_PLUGIN_URL . '/js/frontend.js', array( 'jquery' ), iubenda()->version, true );
67
-
68
- $args = array();
69
-
70
- $form_args = array(
71
- 'post_status' => array( 'mapped', 'needs_update' )
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;
132
-
133
- wp_localize_script(
134
- 'iubenda-forms',
135
- 'iubForms',
136
- json_encode( $args )
137
- );
138
-
139
- wp_enqueue_script( 'iubenda-forms' );
140
- }
141
- }
142
-
143
- /**
144
- * Register iubenda form post type.
145
- */
146
- public function register_post_type() {
147
- register_post_type( 'iubenda_form', array(
148
- 'labels' => array(
149
- 'name' => __( 'Forms', 'iubenda' ),
150
- 'singular_name' => __( 'Form', 'iubenda' ),
151
- ),
152
- 'rewrite' => false,
153
- 'query_var' => false,
154
- 'public' => false,
155
- 'capability_type' => 'page'
156
- ) );
157
- }
158
-
159
- /**
160
- * Register iubenda form post status.
161
- */
162
- public function register_post_status() {
163
- foreach ( $this->statuses as $name => $label ) {
164
- if ( $name === 'publish' )
165
- continue;
166
-
167
- register_post_status( $name, array(
168
- 'label' => $label,
169
- 'public' => true,
170
- 'exclude_from_search' => false,
171
- 'show_in_admin_all_list' => true,
172
- 'show_in_admin_status_list' => true,
173
- 'post_type' => array( 'iubenda_form' ),
174
- // 'label_count' => _n_noop( 'Mapped <span class="count">(%s)</span>', 'Mapped <span class="count">(%s)</span>', 'iubenda' ),
175
- ) );
176
- }
177
-
178
- }
179
-
180
- /**
181
- * Get iubenda forms function.
182
- *
183
- * @param type $args
184
- * @return array
185
- */
186
- public function get_forms( $args = array() ) {
187
- $defaults = array(
188
- 'post_status' => 'any',
189
- 'posts_per_page' => -1,
190
- 'offset' => 0,
191
- 'orderby' => 'ID',
192
- 'order' => 'ASC',
193
- 'form_source' => 'any'
194
- );
195
-
196
- $args = wp_parse_args( $args, $defaults );
197
-
198
- $args['post_type'] = 'iubenda_form';
199
-
200
- // specific sources only
201
- if ( $args['form_source'] != 'any' && ( is_string( $args['form_source'] ) || is_array( $args['form_source'] ) ) ) {
202
- $args['meta_query'] = array(
203
- array(
204
- 'key' => '_iub_form_source',
205
- 'value' => $args['form_source'],
206
- 'compare' => 'IN',
207
- ),
208
- );
209
- }
210
-
211
- $q = new WP_Query();
212
-
213
- $posts = $q->query( $args );
214
-
215
- $metakeys = array(
216
- 'form_source',
217
- 'object_type',
218
- 'object_id',
219
- 'form_fields',
220
- 'form_subject',
221
- 'form_preferences',
222
- 'form_exclude',
223
- 'form_legal_notices'
224
- );
225
-
226
- if ( ! empty( $posts ) ) {
227
- foreach ( $posts as $index => $post ) {
228
- // get form data
229
- $metadata_raw = get_metadata( 'post', $post->ID );
230
-
231
- foreach ( $metakeys as $metakey ) {
232
- $metadata = ! empty( $metadata_raw['_iub_' . $metakey][0] ) ? maybe_unserialize( $metadata_raw['_iub_' . $metakey][0] ) : '';
233
-
234
- if ( ! empty( $metadata ) ) {
235
- // unset empty values
236
- if ( is_array( $metadata ) ) {
237
- foreach ( $metadata as $metadata_key => $metadata_value ) {
238
- if ( $metadata_value == '' && ! in_array( $metakey, array( 'form_legal_notices' ) ) )
239
- unset( $metadata[$metadata_key] );
240
- }
241
- }
242
-
243
- $posts[$index]->{$metakey} = $metadata;
244
- }
245
- /* object id needs to ba an integer
246
- } elseif ( in_array( $metakey, array( 'object_id' ) ) ) {
247
- $posts[$index]->{$metakey} = ! empty( $metadata ) ? absint( $metadata ) : 0;
248
- }
249
- */
250
- }
251
- }
252
- }
253
-
254
- return $posts;
255
- }
256
-
257
- /**
258
- * Get form function.
259
- *
260
- * @param int
261
- * @return object
262
- */
263
- public function get_form( $id ) {
264
- $form_id = ! empty( $id ) ? absint( $id ) : 0;
265
-
266
- if ( ! $form_id )
267
- return false;
268
-
269
- $form = get_post( $form_id );
270
-
271
- if ( ! $form )
272
- return false;
273
-
274
- $metakeys = array(
275
- 'form_source',
276
- 'object_type',
277
- 'object_id',
278
- 'form_fields',
279
- 'form_subject',
280
- 'form_preferences',
281
- 'form_exclude',
282
- 'form_legal_notices'
283
- );
284
-
285
- // get form data
286
- $metadata = get_metadata( 'post', $form->ID );
287
-
288
- foreach ( $metakeys as $metakey ) {
289
- $form->{$metakey} = ! empty( $metadata['_iub_' . $metakey][0] ) ? maybe_unserialize( $metadata['_iub_' . $metakey][0] ) : '';
290
- }
291
-
292
- return $form;
293
- }
294
-
295
- /**
296
- * Delete form function.
297
- *
298
- * @param int
299
- * @return int
300
- */
301
- public function delete_form( $id ) {
302
- $form_id = ! empty( $id ) ? absint( $id ) : 0;
303
-
304
- if ( ! $form_id )
305
- return false;
306
-
307
- $form = get_post( $form_id );
308
-
309
- if ( ! $form )
310
- return false;
311
-
312
- $result = wp_delete_post( $id, true );
313
-
314
- return $result;
315
- }
316
-
317
- /**
318
- * Insert form function.
319
- *
320
- * @param array $args
321
- * @return int
322
- */
323
- public function save_form( $args = array() ) {
324
- $defaults = array(
325
- 'ID' => 0,
326
- 'status' => 'publish',
327
- 'object_type' => 'post', // object type where the form data is stored
328
- 'object_id' => 0, // unique object id
329
- 'form_source' => '', // source slug
330
- 'form_title' => '', // form title
331
- 'form_date' => current_time( 'mysql' ), // form last modified date
332
- 'form_fields' => array(), // form field names array
333
- 'form_subject' => array(), // mapped form with iubenda consent subject param
334
- 'form_preferences' => array(), // mapped form with iubenda consent preferences param
335
- 'form_exclude' => array(), // mapped form with iubenda consent exclude param
336
- 'form_legal_notices' => array() // form legal notices
337
- );
338
-
339
- $args = wp_parse_args( $args, $defaults );
340
-
341
- // sanitize args
342
- $args['ID'] = ! empty( $args['ID'] ) ? absint( $args['ID'] ) : 0;
343
- $args['status'] = ! empty( $args['status'] ) && in_array( $args['status'], array_keys( $this->statuses ) ) ? $args['status'] : 'publish';
344
- $args['object_type'] = 'post';
345
- $args['object_id'] = ! empty( $args['object_id'] ) ? (int) $args['object_id'] : 0;
346
- $args['form_source'] = ! empty( $args['form_source'] ) && in_array( $args['form_source'], array_keys( $this->sources ) ) ? $args['form_source'] : '';
347
- $args['form_title'] = ! empty( $args['form_title'] ) ? esc_html( $args['form_title'] ) : '';
348
- $args['form_date'] = date( 'Y-m-d H:i:s', ( ! empty( $args['form_date'] ) ? strtotime( $args['form_date'] ) : current_time( 'mysql' ) ) );
349
- $args['form_fields'] = ! empty( $args['form_fields'] ) && is_array( $args['form_fields'] ) ? $args['form_fields'] : array();
350
- $args['form_subject'] = ! empty( $args['form_subject'] ) && is_array( $args['form_subject'] ) ? array_map( 'esc_attr', $args['form_subject'] ) : array();
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 ) {
360
- if ( ! empty( $form_field ) && is_array( $form_field ) ) {
361
- $form_fields[] = array_map( 'esc_attr', $form_field );
362
- } else {
363
- $form_fields[] = esc_attr( $form_field );
364
- }
365
- }
366
- }
367
-
368
- // echo '<pre>'; print_r( $args ); echo '</pre>'; exit;
369
-
370
- // bail if any issues
371
- if ( ! $args['form_source'] || ! $args['form_fields'] )
372
- return false;
373
-
374
- $post = $args['ID'] !== 0 ? get_post( $args['ID'] ) : false;
375
- $update = empty( $post ) ? false : true;
376
-
377
- // insert new form
378
- if ( ! $update ) {
379
- $post_id = wp_insert_post( array(
380
- 'post_type' => 'iubenda_form',
381
- 'post_status' => $args['status'],
382
- 'post_title' => $args['form_title'],
383
- 'post_content' => '',
384
- 'post_date' => $args['form_date'],
385
- 'post_modified' => $args['form_date']
386
- ) );
387
- // update form
388
- } else {
389
- $post_id = wp_update_post( array(
390
- 'ID' => $args['ID'],
391
- 'post_status' => $args['status'],
392
- 'post_modified' => $args['form_date']
393
- ) );
394
- }
395
-
396
- // save form source
397
- if ( isset( $args['form_source'] ) )
398
- update_post_meta( $post_id, '_iub_form_source', $args['form_source'] );
399
-
400
- // save object type
401
- if ( isset( $args['object_type'] ) )
402
- update_post_meta( $post_id, '_iub_object_type', $args['object_type'] );
403
-
404
- // save object id
405
- if ( isset( $args['object_id'] ) )
406
- update_post_meta( $post_id, '_iub_object_id', absint( $args['object_id'] ) );
407
-
408
- // save form fields
409
- if ( isset( $args['form_fields'] ) )
410
- update_post_meta( $post_id, '_iub_form_fields', $form_fields );
411
-
412
- // save form subject
413
- if ( isset( $args['form_subject'] ) )
414
- update_post_meta( $post_id, '_iub_form_subject', $args['form_subject'] );
415
-
416
- // save form preferences
417
- if ( isset( $args['form_preferences'] ) )
418
- update_post_meta( $post_id, '_iub_form_preferences', $args['form_preferences'] );
419
-
420
- // save form exclude
421
- if ( isset( $args['form_exclude'] ) )
422
- update_post_meta( $post_id, '_iub_form_exclude', $args['form_exclude'] );
423
-
424
- // save legal notices
425
- if ( isset( $args['form_legal_notices'] ) )
426
- update_post_meta( $post_id, '_iub_form_legal_notices', $args['form_legal_notices'] );
427
-
428
- return $post_id;
429
- }
430
-
431
- /**
432
- * Autodetect forms action.
433
- *
434
- * @return bool
435
- */
436
- public function autodetect_forms() {
437
- $found_forms = $new_forms = array();
438
-
439
- // get forms from active sources
440
- if ( ! empty( $this->sources ) ) {
441
- foreach ( $this->sources as $source => $source_name ) {
442
- $found_forms[$source] = call_user_func( array( $this, 'get_source_forms' ), $source );
443
- }
444
- }
445
-
446
- // insert forms
447
- if ( ! empty( $found_forms ) ) {
448
- foreach ( $found_forms as $source => $source_forms ) {
449
- if ( ! empty( $source_forms ) ) {
450
-
451
- foreach ( $source_forms as $formdata ) {
452
-
453
- $exists = $this->get_form_by_object_id( array(
454
- 'id' => $formdata['object_id'],
455
- 'source' => $formdata['form_source']
456
- ) );
457
-
458
- // form does not exist
459
- if ( ! $exists ) {
460
- $result = $this->save_form( $formdata );
461
-
462
- if ( $result )
463
- $new_forms['new'] = $result;
464
- } else {
465
- // check for fields changes
466
- $new_fields = array_merge( array_diff( $formdata['form_fields'], $exists->form_fields ), array_diff( $exists->form_fields, $formdata['form_fields'] ) );
467
-
468
- if ( $new_fields ) {
469
- $new_forms['updated'] = $exists->ID;
470
-
471
- // update form
472
- $formdata['ID'] = $exists->ID;
473
-
474
- // update to need status if form is already mapped
475
- if ( $exists->post_status == 'mapped' )
476
- $formdata['status'] = 'needs_update';
477
-
478
- // echo '<pre>'; print_r( $formdata ); echo '</pre>'; exit;
479
-
480
- $result = $this->save_form( $formdata );
481
- }
482
- }
483
- }
484
- }
485
- }
486
- }
487
-
488
- // echo '<pre>'; print_r( $found_forms ); echo '</pre>'; exit;
489
-
490
- return ! empty( $new_forms ) ? $new_forms : array();
491
- }
492
-
493
- /**
494
- * Get source forms.
495
- *
496
- * @param string
497
- * @return array
498
- */
499
- public function get_source_forms( $source = '' ) {
500
- $source = ! empty( $source ) && in_array( $source, array_keys( $this->sources ) ) ? $source : '';
501
- $forms = array();
502
-
503
- $restricted_fields = apply_filters( "iub_{$source}_restricted_fields", array(
504
- 'submit',
505
- 'file',
506
- 'quiz'
507
- ) );
508
-
509
- switch ( $source ) {
510
- case 'wpforms' :
511
- $args = array(
512
- 'post_type' => 'wpforms',
513
- 'no_found_rows' => true,
514
- 'nopaging' => true,
515
- );
516
- $posts = get_posts( $args );
517
-
518
- // echo '<pre>'; print_r( $posts ); echo '</pre>'; exit;
519
-
520
- if ( ! empty( $posts ) ) {
521
- foreach ( $posts as $post ) {
522
- // get form data
523
- $formdata = array(
524
- 'object_type' => 'post', // object type where the form data is stored
525
- 'object_id' => $post->ID, // unique object id
526
- 'form_source' => $source, // source slug
527
- 'form_title' => $post->post_title, // form title
528
- 'form_date' => $post->post_modified, // form last modified date
529
- 'form_fields' => array() // form field names array
530
- );
531
-
532
- $input_fields = array(
533
- 'text',
534
- 'textarea',
535
- 'select',
536
- 'radio',
537
- 'checkbox',
538
- 'gdpr-checkbox',
539
- 'email',
540
- 'address',
541
- 'url',
542
- 'name',
543
- 'hidden',
544
- 'date-time',
545
- 'phone',
546
- 'number',
547
- );
548
-
549
- $fields_raw = function_exists( 'wpforms_get_form_fields' ) ? wpforms_get_form_fields( $post->ID ) : false;
550
-
551
- // echo '<pre>'; print_r( $fields_raw ); echo '</pre>'; exit;
552
-
553
- if ( ! empty( $fields_raw ) ) {
554
- foreach ( $fields_raw as $index => $field ) {
555
- // specific field types only
556
- if ( ! empty( $field['type'] ) && in_array( $field['type'], $input_fields ) ) {
557
- switch ( $field['type'] ) {
558
- case 'name' :
559
- if ( ! empty( $field['format'] ) ) {
560
- switch ( $field['format'] ) {
561
- case 'first-last' :
562
- $formdata['form_fields'][] = array(
563
- 'id' => $field['id'],
564
- 'name' => 'wpforms[fields][' . $index . '][first]',
565
- 'type' => $field['type'],
566
- 'label' => __( 'First name', 'iubenda' )
567
- );
568
- $formdata['form_fields'][] = array(
569
- 'id' => $field['id'],
570
- 'name' => 'wpforms[fields][' . $index . '][last]',
571
- 'type' => $field['type'],
572
- 'label' => __( 'Last name', 'iubenda' )
573
- );
574
- break;
575
- case 'first-middle-last' :
576
- $formdata['form_fields'][] = array(
577
- 'id' => $field['id'],
578
- 'name' => 'wpforms[fields][' . $index . '][first]',
579
- 'type' => $field['type'],
580
- 'label' => __( 'First name', 'iubenda' )
581
- );
582
- $formdata['form_fields'][] = array(
583
- 'id' => $field['id'],
584
- 'name' => 'wpforms[fields][' . $index . '][middle]',
585
- 'type' => $field['type'],
586
- 'label' => __( 'Middle name', 'iubenda' )
587
- );
588
- $formdata['form_fields'][] = array(
589
- 'id' => $field['id'],
590
- 'name' => 'wpforms[fields][' . $index . '][last]',
591
- 'type' => $field['type'],
592
- 'label' => __( 'Last name', 'iubenda' )
593
- );
594
- break;
595
- default :
596
- $formdata['form_fields'][] = array(
597
- 'id' => $field['id'],
598
- 'name' => 'wpforms[fields][' . $index . ']',
599
- 'type' => $field['type'],
600
- 'label' => $field['label']
601
- );
602
- break;
603
- }
604
- } else {
605
- $formdata['form_fields'][] = array(
606
- 'id' => $field['id'],
607
- 'name' => 'wpforms[fields][' . $index . ']',
608
- 'type' => $field['type'],
609
- 'label' => $field['label']
610
- );
611
- }
612
- break;
613
- // fix multiple choice checkbox
614
- case 'checkbox' :
615
- $formdata['form_fields'][] = array(
616
- 'id' => $field['id'],
617
- 'name' => 'wpforms[fields][' . $index . '][]',
618
- 'type' => $field['type'],
619
- 'label' => $field['label']
620
- );
621
- break;
622
- default :
623
- $formdata['form_fields'][] = array(
624
- 'id' => $field['id'],
625
- 'name' => 'wpforms[fields][' . $index . ']',
626
- 'type' => $field['type'],
627
- 'label' => $field['label']
628
- );
629
- }
630
-
631
- }
632
- }
633
- }
634
-
635
- $forms[] = $formdata;
636
- }
637
-
638
- // echo '<pre>'; print_r( $forms ); echo '</pre>'; exit;
639
- }
640
-
641
- break;
642
-
643
- case 'wpcf7' :
644
- $args = array(
645
- 'post_type' => 'wpcf7_contact_form',
646
- 'posts_per_page' => -1
647
- );
648
- $posts = get_posts( $args );
649
-
650
- if ( ! empty( $posts ) ) {
651
- foreach ( $posts as $post ) {
652
- // get form data
653
- $contact_form = class_exists( 'WPCF7_ContactForm' ) ? WPCF7_ContactForm::get_instance( $post->ID ) : false;
654
-
655
- if ( ! empty( $contact_form ) ) {
656
- $formdata = array(
657
- 'object_type' => 'post', // object type where the form data is stored
658
- 'object_id' => $post->ID, // unique object id
659
- 'form_source' => $source, // source slug
660
- 'form_title' => $post->post_title, // form title
661
- 'form_date' => $post->post_modified, // form last modified date
662
- 'form_fields' => array() // form field names array
663
- );
664
-
665
- $fields_raw = $contact_form->scan_form_tags();
666
-
667
- // echo '<pre>'; print_r( $fields_raw ); echo '</pre>'; exit;
668
-
669
- if ( ! empty( $fields_raw ) ) {
670
- foreach ( $fields_raw as $field ) {
671
- // specific field types only
672
- if ( ! empty( $field['basetype'] ) && ! in_array( $field['basetype'], $restricted_fields ) ) {
673
- $formdata['form_fields'][] = $field['name'];
674
- }
675
- }
676
- }
677
-
678
- $forms[] = $formdata;
679
- }
680
-
681
- // echo '<pre>'; print_r( $contact_form ); echo '</pre>'; exit;
682
- }
683
- }
684
-
685
- break;
686
-
687
- case 'woocommerce' :
688
- $checkout_form = '';
689
-
690
- ob_start();
691
-
692
- // Ensure gateways and shipping methods are loaded early.
693
- WC()->payment_gateways();
694
- WC()->shipping();
695
-
696
- /*
697
- * First lets start the session. You cant use here WC_Session directly
698
- * because it's an abstract class. But you can use WC_Session_Handler which
699
- * extends WC_Session
700
- */
701
- WC()->session = new WC_Session_Handler;
702
-
703
- /*
704
- * Next lets create a customer so we can access checkout fields
705
- * If you will check a constructor for WC_Customer class you will see
706
- * that if you will not provide user to create customer it will use some
707
- * default one. Magic.
708
- */
709
- WC()->customer = new WC_Customer;
710
-
711
- // Create a cart contents
712
- WC()->cart = new WC_Cart;
713
-
714
- // Create an abstract order
715
- WC()->order = new WC_Order;
716
-
717
- wc_get_template(
718
- 'checkout/form-checkout.php', array(
719
- 'checkout' => WC()->checkout()
720
- )
721
- );
722
-
723
- wc_get_template(
724
- 'checkout/form-pay.php', array(
725
- 'order' => WC()->order
726
- )
727
- );
728
-
729
- $checkout_form = ob_get_contents();
730
- ob_end_clean();
731
-
732
- if ( ! empty( $checkout_form ) ) {
733
- $formdata = array(
734
- 'object_type' => 'custom', // object type where the form data is stored
735
- 'object_id' => 0, // unique object id
736
- 'form_source' => $source, // source slug
737
- 'form_title' => $this->sources[$source], // form title
738
- 'form_date' => current_time( 'mysql' ), // form last modified date
739
- 'form_fields' => array() // form field names array
740
- );
741
-
742
- $input_fields = array(
743
- 'input',
744
- 'textarea',
745
- 'select'
746
- );
747
-
748
- // DOMDoc parser
749
- if ( iubenda()->options['cs']['parser_engine'] == 'new' ) {
750
- libxml_use_internal_errors( true );
751
-
752
- $document = new DOMDocument();
753
-
754
- // set document arguments
755
- $document->formatOutput = true;
756
- $document->preserveWhiteSpace = false;
757
-
758
- // load HTML
759
- $document->loadHTML( $checkout_form );
760
-
761
- // search for nodes
762
- foreach ( $input_fields as $input_field ) {
763
- $fields_raw = $document->getElementsByTagName( $input_field );
764
-
765
- if ( ! empty( $fields_raw ) && is_object( $fields_raw ) ) {
766
- foreach ( $fields_raw as $field ) {
767
- $field_name = $field->getAttribute( 'name' );
768
- $field_type = $field->getAttribute( 'type' );
769
-
770
- // exclude submit
771
- if ( ! empty( $field_type ) && ! in_array( $field_type, array( 'submit', 'hidden' ) ) )
772
- $formdata['form_fields'][] = $field->getAttribute( 'name' );
773
- }
774
- }
775
- }
776
-
777
- $forms[] = $formdata;
778
-
779
- libxml_use_internal_errors( false );
780
-
781
- // Simple HTML Dom parser
782
- } else {
783
- $html = str_get_html( $checkout_form, $lowercase = true, $force_tags_closed = true, $strip = false );
784
-
785
- if ( is_object( $html ) ) {
786
- // search for nodes
787
- foreach ( $input_fields as $input_field ) {
788
- $fields_raw = $html->find( $input_field );
789
-
790
- if ( is_array( $fields_raw ) ) {
791
- foreach ( $fields_raw as $field ) {
792
- $field_name = $field->name;
793
- $field_type = $field->type;
794
-
795
- // exclude submit
796
- if ( ! empty( $field_type ) && ! in_array( $field_type, array( 'submit', 'hidden' ) ) )
797
- $formdata['form_fields'][] = $field->getAttribute( 'name' );
798
- }
799
- }
800
- }
801
-
802
- $forms[] = $formdata;
803
-
804
- }
805
- }
806
-
807
- }
808
-
809
- /*
810
- echo '<pre>';
811
- print_r( $checkout_form );
812
- echo '</pre>';
813
- exit;
814
- */
815
- break;
816
-
817
- case 'wp_comment_form' :
818
- $comment_form = '';
819
-
820
- // get comment form for logged out user
821
- $current_user_id = get_current_user_id();
822
-
823
- // get first post
824
- $post_args = array(
825
- 'numberposts' => 1,
826
- 'orderby' => 'ID',
827
- 'order' => 'ASC',
828
- 'fields' => 'ids'
829
- );
830
-
831
- $posts = get_posts( $post_args );
832
-
833
- // get comment form
834
- if ( ! empty( $posts ) ) {
835
- wp_set_current_user( 0 );
836
-
837
- ob_start();
838
-
839
- comment_form( array(), $posts[0] );
840
-
841
- $comment_form = ob_get_contents();
842
- ob_end_clean();
843
-
844
- wp_set_current_user( $current_user_id );
845
- }
846
-
847
- if ( ! empty( $comment_form ) ) {
848
- $formdata = array(
849
- 'object_type' => 'custom', // object type where the form data is stored
850
- 'object_id' => 0, // unique object id
851
- 'form_source' => $source, // source slug
852
- 'form_title' => $this->sources[$source], // form title
853
- 'form_date' => current_time( 'mysql' ), // form last modified date
854
- 'form_fields' => array() // form field names array
855
- );
856
-
857
- $input_fields = array(
858
- 'input',
859
- 'textarea',
860
- 'select'
861
- );
862
-
863
- // DOMDoc parser
864
- if ( iubenda()->options['cs']['parser_engine'] == 'new' ) {
865
- libxml_use_internal_errors( true );
866
-
867
- $document = new DOMDocument();
868
-
869
- // set document arguments
870
- $document->formatOutput = true;
871
- $document->preserveWhiteSpace = false;
872
-
873
- // load HTML
874
- $document->loadHTML( $comment_form );
875
-
876
- // search for nodes
877
- foreach ( $input_fields as $input_field ) {
878
- $fields_raw = $document->getElementsByTagName( $input_field );
879
-
880
- if ( ! empty( $fields_raw ) && is_object( $fields_raw ) ) {
881
- foreach ( $fields_raw as $field ) {
882
- $field_name = $field->getAttribute( 'name' );
883
- $field_type = $field->getAttribute( 'type' );
884
-
885
- // exclude submit
886
- if ( ! empty( $field_type ) && ! in_array( $field_type, array( 'submit' ) ) )
887
- $formdata['form_fields'][] = $field->getAttribute( 'name' );
888
- }
889
- }
890
- }
891
-
892
- $forms[] = $formdata;
893
-
894
- libxml_use_internal_errors( false );
895
-
896
- // Simple HTML Dom parser
897
- } else {
898
- $html = str_get_html( $comment_form, $lowercase = true, $force_tags_closed = true, $strip = false );
899
-
900
- if ( is_object( $html ) ) {
901
- // search for nodes
902
- foreach ( $input_fields as $input_field ) {
903
- $fields_raw = $html->find( $input_field );
904
-
905
- if ( is_array( $fields_raw ) ) {
906
- foreach ( $fields_raw as $field ) {
907
- $field_name = $field->name;
908
- $field_type = $field->type;
909
-
910
- // exclude submit
911
- if ( ! empty( $field_type ) && ! in_array( $field_type, array( 'submit' ) ) )
912
- $formdata['form_fields'][] = $field->getAttribute( 'name' );
913
- }
914
- }
915
- }
916
-
917
- $forms[] = $formdata;
918
-
919
- }
920
- }
921
- }
922
-
923
- break;
924
- }
925
-
926
- return $forms;
927
- }
928
-
929
- /**
930
- * Get Post object by post_meta query
931
- *
932
- * @return array
933
- */
934
- public function get_form_by_object_id( $args = array() ) {
935
- // parse incoming $args into an array and merge it with $defaults
936
- $args = wp_parse_args( $args );
937
-
938
- // grab page
939
- $args = array(
940
- 'meta_query' => array(
941
- array(
942
- 'key' => '_iub_object_id',
943
- 'value' => $args['id'],
944
- ),
945
- array(
946
- 'key' => '_iub_form_source',
947
- 'value' => $args['source'],
948
- )
949
- ),
950
- 'post_type' => 'iubenda_form',
951
- 'post_status' => 'any',
952
- 'posts_per_page' => '1',
953
- 'fields' => 'ids'
954
- );
955
-
956
- // run query
957
- $posts = get_posts( $args );
958
-
959
- // check result
960
- if ( ! $posts || is_wp_error( $posts ) )
961
- return false;
962
-
963
- $form = $this->get_form( $posts[0] );
964
-
965
- // kick back results
966
- return $form;
967
- }
968
-
969
- }
1
+ <?php
2
+ // exit if accessed directly
3
+ if ( ! defined( 'ABSPATH' ) )
4
+ exit;
5
+
6
+ /**
7
+ * iubenda_Forms class.
8
+ *
9
+ * @class iubenda_Forms
10
+ */
11
+ class iubenda_Forms {
12
+
13
+ public $sources = array();
14
+ public $statuses = array();
15
+
16
+ /**
17
+ * Class constructor.
18
+ */
19
+ public function __construct() {
20
+ // actions
21
+ add_action( 'plugins_loaded', array( $this, 'init' ) );
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
+ /**
28
+ * Initialize forms data.
29
+ *
30
+ * @return void
31
+ */
32
+ public function init() {
33
+ // WOrdPress commenting form
34
+ $this->sources['wp_comment_form'] = 'WordPress Comment';
35
+
36
+ // check if Contact Form 7 is active
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';
49
+ }
50
+
51
+ $this->sources = apply_filters( 'iub_supported_form_sources', $this->sources );
52
+
53
+ $this->statuses = array(
54
+ 'publish' => _x( 'To Map', 'post status', 'iubenda' ),
55
+ 'mapped' => _x( 'Mapped', 'post status', 'iubenda' ),
56
+ 'needs_update' => _x( 'Needs Update', 'post status', 'iubenda' ),
57
+ // 'trash' => _x( 'Ignored', 'post status', 'iubenda' )
58
+ );
59
+ }
60
+
61
+ /**
62
+ * Enqueue frontend script.
63
+ */
64
+ public function wp_enqueue_scripts() {
65
+ if ( ! empty( iubenda()->options['cons']['public_api_key'] ) ) {
66
+ wp_register_script( 'iubenda-forms', IUBENDA_PLUGIN_URL . '/js/frontend.js', array( 'jquery' ), iubenda()->version, true );
67
+
68
+ $args = array();
69
+
70
+ $form_args = array(
71
+ 'post_status' => array( 'mapped', 'needs_update' )
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;
132
+
133
+ wp_localize_script(
134
+ 'iubenda-forms',
135
+ 'iubForms',
136
+ json_encode( $args )
137
+ );
138
+
139
+ wp_enqueue_script( 'iubenda-forms' );
140
+ }
141
+ }
142
+
143
+ /**
144
+ * Register iubenda form post type.
145
+ */
146
+ public function register_post_type() {
147
+ register_post_type( 'iubenda_form', array(
148
+ 'labels' => array(
149
+ 'name' => __( 'Forms', 'iubenda' ),
150
+ 'singular_name' => __( 'Form', 'iubenda' ),
151
+ ),
152
+ 'rewrite' => false,
153
+ 'query_var' => false,
154
+ 'public' => false,
155
+ 'capability_type' => 'page'
156
+ ) );
157
+ }
158
+
159
+ /**
160
+ * Register iubenda form post status.
161
+ */
162
+ public function register_post_status() {
163
+ foreach ( $this->statuses as $name => $label ) {
164
+ if ( $name === 'publish' )
165
+ continue;
166
+
167
+ register_post_status( $name, array(
168
+ 'label' => $label,
169
+ 'public' => true,
170
+ 'exclude_from_search' => false,
171
+ 'show_in_admin_all_list' => true,
172
+ 'show_in_admin_status_list' => true,
173
+ 'post_type' => array( 'iubenda_form' ),
174
+ // 'label_count' => _n_noop( 'Mapped <span class="count">(%s)</span>', 'Mapped <span class="count">(%s)</span>', 'iubenda' ),
175
+ ) );
176
+ }
177
+
178
+ }
179
+
180
+ /**
181
+ * Get iubenda forms function.
182
+ *
183
+ * @param type $args
184
+ * @return array
185
+ */
186
+ public function get_forms( $args = array() ) {
187
+ $defaults = array(
188
+ 'post_status' => 'any',
189
+ 'posts_per_page' => -1,
190
+ 'offset' => 0,
191
+ 'orderby' => 'ID',
192
+ 'order' => 'ASC',
193
+ 'form_source' => 'any'
194
+ );
195
+
196
+ $args = wp_parse_args( $args, $defaults );
197
+
198
+ $args['post_type'] = 'iubenda_form';
199
+
200
+ // specific sources only
201
+ if ( $args['form_source'] != 'any' && ( is_string( $args['form_source'] ) || is_array( $args['form_source'] ) ) ) {
202
+ $args['meta_query'] = array(
203
+ array(
204
+ 'key' => '_iub_form_source',
205
+ 'value' => $args['form_source'],
206
+ 'compare' => 'IN',
207
+ ),
208
+ );
209
+ }
210
+
211
+ $q = new WP_Query();
212
+
213
+ $posts = $q->query( $args );
214
+
215
+ $metakeys = array(
216
+ 'form_source',
217
+ 'object_type',
218
+ 'object_id',
219
+ 'form_fields',
220
+ 'form_subject',
221
+ 'form_preferences',
222
+ 'form_exclude',
223
+ 'form_legal_notices'
224
+ );
225
+
226
+ if ( ! empty( $posts ) ) {
227
+ foreach ( $posts as $index => $post ) {
228
+ // get form data
229
+ $metadata_raw = get_metadata( 'post', $post->ID );
230
+
231
+ foreach ( $metakeys as $metakey ) {
232
+ $metadata = ! empty( $metadata_raw['_iub_' . $metakey][0] ) ? maybe_unserialize( $metadata_raw['_iub_' . $metakey][0] ) : '';
233
+
234
+ if ( ! empty( $metadata ) ) {
235
+ // unset empty values
236
+ if ( is_array( $metadata ) ) {
237
+ foreach ( $metadata as $metadata_key => $metadata_value ) {
238
+ if ( $metadata_value == '' && ! in_array( $metakey, array( 'form_legal_notices' ) ) )
239
+ unset( $metadata[$metadata_key] );
240
+ }
241
+ }
242
+
243
+ $posts[$index]->{$metakey} = $metadata;
244
+ }
245
+ /* object id needs to ba an integer
246
+ } elseif ( in_array( $metakey, array( 'object_id' ) ) ) {
247
+ $posts[$index]->{$metakey} = ! empty( $metadata ) ? absint( $metadata ) : 0;
248
+ }
249
+ */
250
+ }
251
+ }
252
+ }
253
+
254
+ return $posts;
255
+ }
256
+
257
+ /**
258
+ * Get form function.
259
+ *
260
+ * @param int
261
+ * @return object
262
+ */
263
+ public function get_form( $id ) {
264
+ $form_id = ! empty( $id ) ? absint( $id ) : 0;
265
+
266
+ if ( ! $form_id )
267
+ return false;
268
+
269
+ $form = get_post( $form_id );
270
+
271
+ if ( ! $form )
272
+ return false;
273
+
274
+ $metakeys = array(
275
+ 'form_source',
276
+ 'object_type',
277
+ 'object_id',
278
+ 'form_fields',
279
+ 'form_subject',
280
+ 'form_preferences',
281
+ 'form_exclude',
282
+ 'form_legal_notices'
283
+ );
284
+
285
+ // get form data
286
+ $metadata = get_metadata( 'post', $form->ID );
287
+
288
+ foreach ( $metakeys as $metakey ) {
289
+ $form->{$metakey} = ! empty( $metadata['_iub_' . $metakey][0] ) ? maybe_unserialize( $metadata['_iub_' . $metakey][0] ) : '';
290
+ }
291
+
292
+ return $form;
293
+ }
294
+
295
+ /**
296
+ * Delete form function.
297
+ *
298
+ * @param int
299
+ * @return int
300
+ */
301
+ public function delete_form( $id ) {
302
+ $form_id = ! empty( $id ) ? absint( $id ) : 0;
303
+
304
+ if ( ! $form_id )
305
+ return false;
306
+
307
+ $form = get_post( $form_id );
308
+
309
+ if ( ! $form )
310
+ return false;
311
+
312
+ $result = wp_delete_post( $id, true );
313
+
314
+ return $result;
315
+ }
316
+
317
+ /**
318
+ * Insert form function.
319
+ *
320
+ * @param array $args
321
+ * @return int
322
+ */
323
+ public function save_form( $args = array() ) {
324
+ $defaults = array(
325
+ 'ID' => 0,
326
+ 'status' => 'publish',
327
+ 'object_type' => 'post', // object type where the form data is stored
328
+ 'object_id' => 0, // unique object id
329
+ 'form_source' => '', // source slug
330
+ 'form_title' => '', // form title
331
+ 'form_date' => current_time( 'mysql' ), // form last modified date
332
+ 'form_fields' => array(), // form field names array
333
+ 'form_subject' => array(), // mapped form with iubenda consent subject param
334
+ 'form_preferences' => array(), // mapped form with iubenda consent preferences param
335
+ 'form_exclude' => array(), // mapped form with iubenda consent exclude param
336
+ 'form_legal_notices' => array() // form legal notices
337
+ );
338
+
339
+ $args = wp_parse_args( $args, $defaults );
340
+
341
+ // sanitize args
342
+ $args['ID'] = ! empty( $args['ID'] ) ? absint( $args['ID'] ) : 0;
343
+ $args['status'] = ! empty( $args['status'] ) && in_array( $args['status'], array_keys( $this->statuses ) ) ? $args['status'] : 'publish';
344
+ $args['object_type'] = 'post';
345
+ $args['object_id'] = ! empty( $args['object_id'] ) ? (int) $args['object_id'] : 0;
346
+ $args['form_source'] = ! empty( $args['form_source'] ) && in_array( $args['form_source'], array_keys( $this->sources ) ) ? $args['form_source'] : '';
347
+ $args['form_title'] = ! empty( $args['form_title'] ) ? esc_html( $args['form_title'] ) : '';
348
+ $args['form_date'] = date( 'Y-m-d H:i:s', ( ! empty( $args['form_date'] ) ? strtotime( $args['form_date'] ) : current_time( 'mysql' ) ) );
349
+ $args['form_fields'] = ! empty( $args['form_fields'] ) && is_array( $args['form_fields'] ) ? $args['form_fields'] : array();
350
+ $args['form_subject'] = ! empty( $args['form_subject'] ) && is_array( $args['form_subject'] ) ? array_map( 'esc_attr', $args['form_subject'] ) : array();
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 ) {
360
+ if ( ! empty( $form_field ) && is_array( $form_field ) ) {
361
+ $form_fields[] = array_map( 'esc_attr', $form_field );
362
+ } else {
363
+ $form_fields[] = esc_attr( $form_field );
364
+ }
365
+ }
366
+ }
367
+
368
+ // echo '<pre>'; print_r( $args ); echo '</pre>'; exit;
369
+
370
+ // bail if any issues
371
+ if ( ! $args['form_source'] || ! $args['form_fields'] )
372
+ return false;
373
+
374
+ $post = $args['ID'] !== 0 ? get_post( $args['ID'] ) : false;
375
+ $update = empty( $post ) ? false : true;
376
+
377
+ // insert new form
378
+ if ( ! $update ) {
379
+ $post_id = wp_insert_post( array(
380
+ 'post_type' => 'iubenda_form',
381
+ 'post_status' => $args['status'],
382
+ 'post_title' => $args['form_title'],
383
+ 'post_content' => '',
384
+ 'post_date' => $args['form_date'],
385
+ 'post_modified' => $args['form_date']
386
+ ) );
387
+ // update form
388
+ } else {
389
+ $post_id = wp_update_post( array(
390
+ 'ID' => $args['ID'],
391
+ 'post_status' => $args['status'],
392
+ 'post_modified' => $args['form_date']
393
+ ) );
394
+ }
395
+
396
+ // save form source
397
+ if ( isset( $args['form_source'] ) )
398
+ update_post_meta( $post_id, '_iub_form_source', $args['form_source'] );
399
+
400
+ // save object type
401
+ if ( isset( $args['object_type'] ) )
402
+ update_post_meta( $post_id, '_iub_object_type', $args['object_type'] );
403
+
404
+ // save object id
405
+ if ( isset( $args['object_id'] ) )
406
+ update_post_meta( $post_id, '_iub_object_id', absint( $args['object_id'] ) );
407
+
408
+ // save form fields
409
+ if ( isset( $args['form_fields'] ) )
410
+ update_post_meta( $post_id, '_iub_form_fields', $form_fields );
411
+
412
+ // save form subject
413
+ if ( isset( $args['form_subject'] ) )
414
+ update_post_meta( $post_id, '_iub_form_subject', $args['form_subject'] );
415
+
416
+ // save form preferences
417
+ if ( isset( $args['form_preferences'] ) )
418
+ update_post_meta( $post_id, '_iub_form_preferences', $args['form_preferences'] );
419
+
420
+ // save form exclude
421
+ if ( isset( $args['form_exclude'] ) )
422
+ update_post_meta( $post_id, '_iub_form_exclude', $args['form_exclude'] );
423
+
424
+ // save legal notices
425
+ if ( isset( $args['form_legal_notices'] ) )
426
+ update_post_meta( $post_id, '_iub_form_legal_notices', $args['form_legal_notices'] );
427
+
428
+ return $post_id;
429
+ }
430
+
431
+ /**
432
+ * Autodetect forms action.
433
+ *
434
+ * @return bool
435
+ */
436
+ public function autodetect_forms() {
437
+ $found_forms = $new_forms = array();
438
+
439
+ // get forms from active sources
440
+ if ( ! empty( $this->sources ) ) {
441
+ foreach ( $this->sources as $source => $source_name ) {
442
+ $found_forms[$source] = call_user_func( array( $this, 'get_source_forms' ), $source );
443
+ }
444
+ }
445
+
446
+ // insert forms
447
+ if ( ! empty( $found_forms ) ) {
448
+ foreach ( $found_forms as $source => $source_forms ) {
449
+ if ( ! empty( $source_forms ) ) {
450
+
451
+ foreach ( $source_forms as $formdata ) {
452
+
453
+ $exists = $this->get_form_by_object_id( array(
454
+ 'id' => $formdata['object_id'],
455
+ 'source' => $formdata['form_source']
456
+ ) );
457
+
458
+ // form does not exist
459
+ if ( ! $exists ) {
460
+ $result = $this->save_form( $formdata );
461
+
462
+ if ( $result )
463
+ $new_forms['new'] = $result;
464
+ } else {
465
+ // check for fields changes
466
+ $new_fields = array_merge( array_diff( $formdata['form_fields'], $exists->form_fields ), array_diff( $exists->form_fields, $formdata['form_fields'] ) );
467
+
468
+ if ( $new_fields ) {
469
+ $new_forms['updated'] = $exists->ID;
470
+
471
+ // update form
472
+ $formdata['ID'] = $exists->ID;
473
+
474
+ // update to need status if form is already mapped
475
+ if ( $exists->post_status == 'mapped' )
476
+ $formdata['status'] = 'needs_update';
477
+
478
+ // echo '<pre>'; print_r( $formdata ); echo '</pre>'; exit;
479
+
480
+ $result = $this->save_form( $formdata );
481
+ }
482
+ }
483
+ }
484
+ }
485
+ }
486
+ }
487
+
488
+ // echo '<pre>'; print_r( $found_forms ); echo '</pre>'; exit;
489
+
490
+ return ! empty( $new_forms ) ? $new_forms : array();
491
+ }
492
+
493
+ /**
494
+ * Get source forms.
495
+ *
496
+ * @param string
497
+ * @return array
498
+ */
499
+ public function get_source_forms( $source = '' ) {
500
+ $source = ! empty( $source ) && in_array( $source, array_keys( $this->sources ) ) ? $source : '';
501
+ $forms = array();
502
+
503
+ $restricted_fields = apply_filters( "iub_{$source}_restricted_fields", array(
504
+ 'submit',
505
+ 'file',
506
+ 'quiz'
507
+ ) );
508
+
509
+ switch ( $source ) {
510
+ case 'wpforms' :
511
+ $args = array(
512
+ 'post_type' => 'wpforms',
513
+ 'no_found_rows' => true,
514
+ 'nopaging' => true,
515
+ );
516
+ $posts = get_posts( $args );
517
+
518
+ // echo '<pre>'; print_r( $posts ); echo '</pre>'; exit;
519
+
520
+ if ( ! empty( $posts ) ) {
521
+ foreach ( $posts as $post ) {
522
+ // get form data
523
+ $formdata = array(
524
+ 'object_type' => 'post', // object type where the form data is stored
525
+ 'object_id' => $post->ID, // unique object id
526
+ 'form_source' => $source, // source slug
527
+ 'form_title' => $post->post_title, // form title
528
+ 'form_date' => $post->post_modified, // form last modified date
529
+ 'form_fields' => array() // form field names array
530
+ );
531
+
532
+ $input_fields = array(
533
+ 'text',
534
+ 'textarea',
535
+ 'select',
536
+ 'radio',
537
+ 'checkbox',
538
+ 'gdpr-checkbox',
539
+ 'email',
540
+ 'address',
541
+ 'url',
542
+ 'name',
543
+ 'hidden',
544
+ 'date-time',
545
+ 'phone',
546
+ 'number',
547
+ );
548
+
549
+ $fields_raw = function_exists( 'wpforms_get_form_fields' ) ? wpforms_get_form_fields( $post->ID ) : false;
550
+
551
+ // echo '<pre>'; print_r( $fields_raw ); echo '</pre>'; exit;
552
+
553
+ if ( ! empty( $fields_raw ) ) {
554
+ foreach ( $fields_raw as $index => $field ) {
555
+ // specific field types only
556
+ if ( ! empty( $field['type'] ) && in_array( $field['type'], $input_fields ) ) {
557
+ switch ( $field['type'] ) {
558
+ case 'name' :
559
+ if ( ! empty( $field['format'] ) ) {
560
+ switch ( $field['format'] ) {
561
+ case 'first-last' :
562
+ $formdata['form_fields'][] = array(
563
+ 'id' => $field['id'],
564
+ 'name' => 'wpforms[fields][' . $index . '][first]',
565
+ 'type' => $field['type'],
566
+ 'label' => __( 'First name', 'iubenda' )
567
+ );
568
+ $formdata['form_fields'][] = array(
569
+ 'id' => $field['id'],
570
+ 'name' => 'wpforms[fields][' . $index . '][last]',
571
+ 'type' => $field['type'],
572
+ 'label' => __( 'Last name', 'iubenda' )
573
+ );
574
+ break;
575
+ case 'first-middle-last' :
576
+ $formdata['form_fields'][] = array(
577
+ 'id' => $field['id'],
578
+ 'name' => 'wpforms[fields][' . $index . '][first]',
579
+ 'type' => $field['type'],
580
+ 'label' => __( 'First name', 'iubenda' )
581
+ );
582
+ $formdata['form_fields'][] = array(
583
+ 'id' => $field['id'],
584
+ 'name' => 'wpforms[fields][' . $index . '][middle]',
585
+ 'type' => $field['type'],
586
+ 'label' => __( 'Middle name', 'iubenda' )
587
+ );
588
+ $formdata['form_fields'][] = array(
589
+ 'id' => $field['id'],
590
+ 'name' => 'wpforms[fields][' . $index . '][last]',
591
+ 'type' => $field['type'],
592
+ 'label' => __( 'Last name', 'iubenda' )
593
+ );
594
+ break;
595
+ default :
596
+ $formdata['form_fields'][] = array(
597
+ 'id' => $field['id'],
598
+ 'name' => 'wpforms[fields][' . $index . ']',
599
+ 'type' => $field['type'],
600
+ 'label' => $field['label']
601
+ );
602
+ break;
603
+ }
604
+ } else {
605
+ $formdata['form_fields'][] = array(
606
+ 'id' => $field['id'],
607
+ 'name' => 'wpforms[fields][' . $index . ']',
608
+ 'type' => $field['type'],
609
+ 'label' => $field['label']
610
+ );
611
+ }
612
+ break;
613
+ // fix multiple choice checkbox
614
+ case 'checkbox' :
615
+ $formdata['form_fields'][] = array(
616
+ 'id' => $field['id'],
617
+ 'name' => 'wpforms[fields][' . $index . '][]',
618
+ 'type' => $field['type'],
619
+ 'label' => $field['label']
620
+ );
621
+ break;
622
+ default :
623
+ $formdata['form_fields'][] = array(
624
+ 'id' => $field['id'],
625
+ 'name' => 'wpforms[fields][' . $index . ']',
626
+ 'type' => $field['type'],
627
+ 'label' => $field['label']
628
+ );
629
+ }
630
+
631
+ }
632
+ }
633
+ }
634
+
635
+ $forms[] = $formdata;
636
+ }
637
+
638
+ // echo '<pre>'; print_r( $forms ); echo '</pre>'; exit;
639
+ }
640
+
641
+ break;
642
+
643
+ case 'wpcf7' :
644
+ $args = array(
645
+ 'post_type' => 'wpcf7_contact_form',
646
+ 'posts_per_page' => -1
647
+ );
648
+ $posts = get_posts( $args );
649
+
650
+ if ( ! empty( $posts ) ) {
651
+ foreach ( $posts as $post ) {
652
+ // get form data
653
+ $contact_form = class_exists( 'WPCF7_ContactForm' ) ? WPCF7_ContactForm::get_instance( $post->ID ) : false;
654
+
655
+ if ( ! empty( $contact_form ) ) {
656
+ $formdata = array(
657
+ 'object_type' => 'post', // object type where the form data is stored
658
+ 'object_id' => $post->ID, // unique object id
659
+ 'form_source' => $source, // source slug
660
+ 'form_title' => $post->post_title, // form title
661
+ 'form_date' => $post->post_modified, // form last modified date
662
+ 'form_fields' => array() // form field names array
663
+ );
664
+
665
+ $fields_raw = $contact_form->scan_form_tags();
666
+
667
+ // echo '<pre>'; print_r( $fields_raw ); echo '</pre>'; exit;
668
+
669
+ if ( ! empty( $fields_raw ) ) {
670
+ foreach ( $fields_raw as $field ) {
671
+ // specific field types only
672
+ if ( ! empty( $field['basetype'] ) && ! in_array( $field['basetype'], $restricted_fields ) ) {
673
+ $formdata['form_fields'][] = $field['name'];
674
+ }
675
+ }
676
+ }
677
+
678
+ $forms[] = $formdata;
679
+ }
680
+
681
+ // echo '<pre>'; print_r( $contact_form ); echo '</pre>'; exit;
682
+ }
683
+ }
684
+
685
+ break;
686
+
687
+ case 'woocommerce' :
688
+ $checkout_form = '';
689
+
690
+ ob_start();
691
+
692
+ // Ensure gateways and shipping methods are loaded early.
693
+ WC()->payment_gateways();
694
+ WC()->shipping();
695
+
696
+ /*
697
+ * First lets start the session. You cant use here WC_Session directly
698
+ * because it's an abstract class. But you can use WC_Session_Handler which
699
+ * extends WC_Session
700
+ */
701
+ WC()->session = new WC_Session_Handler;
702
+
703
+ /*
704
+ * Next lets create a customer so we can access checkout fields
705
+ * If you will check a constructor for WC_Customer class you will see
706
+ * that if you will not provide user to create customer it will use some
707
+ * default one. Magic.
708
+ */
709
+ WC()->customer = new WC_Customer;
710
+
711
+ // Create a cart contents
712
+ WC()->cart = new WC_Cart;
713
+
714
+ // Create an abstract order
715
+ WC()->order = new WC_Order;
716
+
717
+ wc_get_template(
718
+ 'checkout/form-checkout.php', array(
719
+ 'checkout' => WC()->checkout()
720
+ )
721
+ );
722
+
723
+ wc_get_template(
724
+ 'checkout/form-pay.php', array(
725
+ 'order' => WC()->order
726
+ )
727
+ );
728
+
729
+ $checkout_form = ob_get_contents();
730
+ ob_end_clean();
731
+
732
+ if ( ! empty( $checkout_form ) ) {
733
+ $formdata = array(
734
+ 'object_type' => 'custom', // object type where the form data is stored
735
+ 'object_id' => 0, // unique object id
736
+ 'form_source' => $source, // source slug
737
+ 'form_title' => $this->sources[$source], // form title
738
+ 'form_date' => current_time( 'mysql' ), // form last modified date
739
+ 'form_fields' => array() // form field names array
740
+ );
741
+
742
+ $input_fields = array(
743
+ 'input',
744
+ 'textarea',
745
+ 'select'
746
+ );
747
+
748
+ // DOMDoc parser
749
+ if ( iubenda()->options['cs']['parser_engine'] == 'new' ) {
750
+ libxml_use_internal_errors( true );
751
+
752
+ $document = new DOMDocument();
753
+
754
+ // set document arguments
755
+ $document->formatOutput = true;
756
+ $document->preserveWhiteSpace = false;
757
+
758
+ // load HTML
759
+ $document->loadHTML( $checkout_form );
760
+
761
+ // search for nodes
762
+ foreach ( $input_fields as $input_field ) {
763
+ $fields_raw = $document->getElementsByTagName( $input_field );
764
+
765
+ if ( ! empty( $fields_raw ) && is_object( $fields_raw ) ) {
766
+ foreach ( $fields_raw as $field ) {
767
+ $field_name = $field->getAttribute( 'name' );
768
+ $field_type = $field->getAttribute( 'type' );
769
+
770
+ // exclude submit
771
+ if ( ! empty( $field_type ) && ! in_array( $field_type, array( 'submit', 'hidden' ) ) )
772
+ $formdata['form_fields'][] = $field->getAttribute( 'name' );
773
+ }
774
+ }
775
+ }
776
+
777
+ $forms[] = $formdata;
778
+
779
+ libxml_use_internal_errors( false );
780
+
781
+ // Simple HTML Dom parser
782
+ } else {
783
+ $html = str_get_html( $checkout_form, $lowercase = true, $force_tags_closed = true, $strip = false );
784
+
785
+ if ( is_object( $html ) ) {
786
+ // search for nodes
787
+ foreach ( $input_fields as $input_field ) {
788
+ $fields_raw = $html->find( $input_field );
789
+
790
+ if ( is_array( $fields_raw ) ) {
791
+ foreach ( $fields_raw as $field ) {
792
+ $field_name = $field->name;
793
+ $field_type = $field->type;
794
+
795
+ // exclude submit
796
+ if ( ! empty( $field_type ) && ! in_array( $field_type, array( 'submit', 'hidden' ) ) )
797
+ $formdata['form_fields'][] = $field->getAttribute( 'name' );
798
+ }
799
+ }
800
+ }
801
+
802
+ $forms[] = $formdata;
803
+
804
+ }
805
+ }
806
+
807
+ }
808
+
809
+ /*
810
+ echo '<pre>';
811
+ print_r( $checkout_form );
812
+ echo '</pre>';
813
+ exit;
814
+ */
815
+ break;
816
+
817
+ case 'wp_comment_form' :
818
+ $comment_form = '';
819
+
820
+ // get comment form for logged out user
821
+ $current_user_id = get_current_user_id();
822
+
823
+ // get first post
824
+ $post_args = array(
825
+ 'numberposts' => 1,
826
+ 'orderby' => 'ID',
827
+ 'order' => 'ASC',
828
+ 'fields' => 'ids'
829
+ );
830
+
831
+ $posts = get_posts( $post_args );
832
+
833
+ // get comment form
834
+ if ( ! empty( $posts ) ) {
835
+ wp_set_current_user( 0 );
836
+
837
+ ob_start();
838
+
839
+ comment_form( array(), $posts[0] );
840
+
841
+ $comment_form = ob_get_contents();
842
+ ob_end_clean();
843
+
844
+ wp_set_current_user( $current_user_id );
845
+ }
846
+
847
+ if ( ! empty( $comment_form ) ) {
848
+ $formdata = array(
849
+ 'object_type' => 'custom', // object type where the form data is stored
850
+ 'object_id' => 0, // unique object id
851
+ 'form_source' => $source, // source slug
852
+ 'form_title' => $this->sources[$source], // form title
853
+ 'form_date' => current_time( 'mysql' ), // form last modified date
854
+ 'form_fields' => array() // form field names array
855
+ );
856
+
857
+ $input_fields = array(
858
+ 'input',
859
+ 'textarea',
860
+ 'select'
861
+ );
862
+
863
+ // DOMDoc parser
864
+ if ( iubenda()->options['cs']['parser_engine'] == 'new' ) {
865
+ libxml_use_internal_errors( true );
866
+
867
+ $document = new DOMDocument();
868
+
869
+ // set document arguments
870
+ $document->formatOutput = true;
871
+ $document->preserveWhiteSpace = false;
872
+
873
+ // load HTML
874
+ $document->loadHTML( $comment_form );
875
+
876
+ // search for nodes
877
+ foreach ( $input_fields as $input_field ) {
878
+ $fields_raw = $document->getElementsByTagName( $input_field );
879
+
880
+ if ( ! empty( $fields_raw ) && is_object( $fields_raw ) ) {
881
+ foreach ( $fields_raw as $field ) {
882
+ $field_name = $field->getAttribute( 'name' );
883
+ $field_type = $field->getAttribute( 'type' );
884
+
885
+ // exclude submit
886
+ if ( ! empty( $field_type ) && ! in_array( $field_type, array( 'submit' ) ) )
887
+ $formdata['form_fields'][] = $field->getAttribute( 'name' );
888
+ }
889
+ }
890
+ }
891
+
892
+ $forms[] = $formdata;
893
+
894
+ libxml_use_internal_errors( false );
895
+
896
+ // Simple HTML Dom parser
897
+ } else {
898
+ $html = str_get_html( $comment_form, $lowercase = true, $force_tags_closed = true, $strip = false );
899
+
900
+ if ( is_object( $html ) ) {
901
+ // search for nodes
902
+ foreach ( $input_fields as $input_field ) {
903
+ $fields_raw = $html->find( $input_field );
904
+
905
+ if ( is_array( $fields_raw ) ) {
906
+ foreach ( $fields_raw as $field ) {
907
+ $field_name = $field->name;
908
+ $field_type = $field->type;
909
+
910
+ // exclude submit
911
+ if ( ! empty( $field_type ) && ! in_array( $field_type, array( 'submit' ) ) )
912
+ $formdata['form_fields'][] = $field->getAttribute( 'name' );
913
+ }
914
+ }
915
+ }
916
+
917
+ $forms[] = $formdata;
918
+
919
+ }
920
+ }
921
+ }
922
+
923
+ break;
924
+ }
925
+
926
+ return $forms;
927
+ }
928
+
929
+ /**
930
+ * Get Post object by post_meta query
931
+ *
932
+ * @return array
933
+ */
934
+ public function get_form_by_object_id( $args = array() ) {
935
+ // parse incoming $args into an array and merge it with $defaults
936
+ $args = wp_parse_args( $args );
937
+
938
+ // grab page
939
+ $args = array(
940
+ 'meta_query' => array(
941
+ array(
942
+ 'key' => '_iub_object_id',
943
+ 'value' => $args['id'],
944
+ ),
945
+ array(
946
+ 'key' => '_iub_form_source',
947
+ 'value' => $args['source'],
948
+ )
949
+ ),
950
+ 'post_type' => 'iubenda_form',
951
+ 'post_status' => 'any',
952
+ 'posts_per_page' => '1',
953
+ 'fields' => 'ids'
954
+ );
955
+
956
+ // run query
957
+ $posts = get_posts( $args );
958
+
959
+ // check result
960
+ if ( ! $posts || is_wp_error( $posts ) )
961
+ return false;
962
+
963
+ $form = $this->get_form( $posts[0] );
964
+
965
+ // kick back results
966
+ return $form;
967
+ }
968
+
969
+ }
includes/settings.php CHANGED
@@ -1,1811 +1,1811 @@
1
- <?php
2
- // exit if accessed directly
3
- if ( ! defined( 'ABSPATH' ) )
4
- exit;
5
-
6
- /**
7
- * iubenda_Settings class.
8
- *
9
- * @class Post_Views_Counter_Settings
10
- */
11
- class iubenda_Settings {
12
-
13
- public $tabs = array();
14
- public $action = '';
15
- public $links = array();
16
- public $notice_types = array( 'error', 'success', 'notice' );
17
- public $subject_fields = array();
18
-
19
- public function __construct() {
20
- // actions
21
- add_action( 'after_setup_theme', array( $this, 'load_defaults' ) );
22
- add_action( 'admin_init', array( $this, 'register_options' ) );
23
- add_action( 'admin_init', array( $this, 'update_plugin' ), 9 );
24
- add_action( 'admin_init', array( $this, 'admin_page_redirect' ), 20 );
25
- add_action( 'admin_init', array( $this, 'process_actions' ), 20 );
26
- add_action( 'admin_init', array( $this, 'maybe_show_notice' ) );
27
- add_action( 'admin_menu', array( $this, 'admin_menu_options' ) );
28
- add_action( 'admin_notices', array( $this, 'settings_errors' ) );
29
- add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
30
- add_action( 'admin_print_styles', array( $this, 'admin_print_styles' ) );
31
- // add_action( 'admin_footer-options-discussion.php', array( $this, 'admin_footer' ) );
32
- add_action( 'wp_ajax_iubenda_dismiss_notice', array( $this, 'dismiss_notice' ) );
33
-
34
- // filters
35
- add_filter( 'submenu_file', array( $this, 'submenu_file' ), 10, 2 );
36
- }
37
-
38
- /**
39
- * Load default settings.
40
- */
41
- public function load_defaults() {
42
- $this->subject_fields = array(
43
- 'id' => __( 'string', 'iubenda' ),
44
- 'email' => __( 'string', 'iubenda' ),
45
- 'first_name' => __( 'string', 'iubenda' ),
46
- 'last_name' => __( 'string', 'iubenda' ),
47
- 'full_name' => __( 'string', 'iubenda' ),
48
- // 'verified' => __( 'boolean', 'iubenda' ),
49
- );
50
-
51
- $this->legal_notices = array(
52
- 'privacy_policy',
53
- 'cookie_policy',
54
- 'terms'
55
- );
56
-
57
- $this->tabs = array(
58
- 'cs' => array(
59
- 'name' => __( 'Cookie Solution', 'iubenda' ),
60
- 'key' => 'iubenda_cookie_law_solution',
61
- 'submit' => 'save_iubenda_options',
62
- 'reset' => 'reset_iubenda_options'
63
- ),
64
- 'cons' => array(
65
- 'name' => __( 'Consent Solution', 'iubenda' ),
66
- 'key' => 'iubenda_consent_solution',
67
- 'submit' => 'save_consent_options',
68
- 'reset' => 'reset_consent_options'
69
- )
70
- );
71
-
72
- $this->tag_types = array(
73
- 0 => __( 'Not set', 'iubenda' ),
74
- 1 => __( 'Strictly necessary', 'iubenda' ),
75
- 2 => __( 'Basic interactions & functionalities', 'iubenda' ),
76
- 3 => __( 'Experience enhancement', 'iubenda' ),
77
- 4 => __( 'Analytics', 'iubenda' ),
78
- 5 => __( 'Targeting & Advertising', 'iubenda' )
79
- );
80
-
81
- $links = array(
82
- 'en' => array(
83
- 'iab' => 'https://www.iubenda.com/en/help/7440-enable-preference-management-iab-framework',
84
- 'guide' => 'https://www.iubenda.com/en/cookie-solution',
85
- 'plugin_page' => 'https://www.iubenda.com/en/help/posts/1215',
86
- 'generating_code' => 'https://www.iubenda.com/en/help/1177-cookie-solution-getting-started',
87
- 'support_forum' => 'https://support.iubenda.com/support/home',
88
- 'documentation' => 'https://www.iubenda.com/en/help/posts/1215'
89
- ),
90
- 'it' => array(
91
- 'iab' => 'https://www.iubenda.com/en/help/7440-enable-preference-management-iab-framework',
92
- 'guide' => 'https://www.iubenda.com/it/cookie-solution',
93
- 'plugin_page' => 'https://www.iubenda.com/it/help/posts/810',
94
- 'generating_code' => 'https://www.iubenda.com/it/help/680-introduzione-cookie-solution',
95
- 'support_forum' => 'https://support.iubenda.com/support/home',
96
- 'documentation' => 'https://www.iubenda.com/it/help/posts/810',
97
- )
98
- );
99
-
100
- $locale = explode( '_', get_locale() );
101
- $locale_code = $locale[0];
102
-
103
- // assign links
104
- $this->links = in_array( $locale_code, array_keys( $links ) ) ? $links[$locale_code] : $links['en'];
105
-
106
- // handle actions
107
- if ( ! empty( $_POST['save'] ) ) {
108
- // update item action
109
- $this->action = 'save';
110
- } else {
111
- $this->action = isset( $_REQUEST['action'] ) && -1 != $_REQUEST['action'] ? esc_attr( $_REQUEST['action'] ) : '';
112
- $this->action = isset( $_REQUEST['action2'] ) && -1 != $_REQUEST['action2'] ? esc_attr( $_REQUEST['action2'] ) : $this->action;
113
- }
114
- }
115
-
116
- /**
117
- * Register plugin options.
118
- *
119
- * @return void
120
- */
121
- public function register_options() {
122
- register_setting( 'iubenda_cookie_law_solution', 'iubenda_cookie_law_solution', array( $this, 'save_cookie_law_options' ) );
123
-
124
- add_settings_section( 'iubenda_cookie_law_solution', '', '', 'iubenda_cookie_law_solution' );
125
- add_settings_field( 'iub_code', __( 'Code', 'iubenda' ), array( $this, 'iub_code' ), 'iubenda_cookie_law_solution', 'iubenda_cookie_law_solution' );
126
- add_settings_field( 'iub_amp_support', __( 'Google AMP', 'iubenda' ), array( $this, 'iub_amp_support' ), 'iubenda_cookie_law_solution', 'iubenda_cookie_law_solution' );
127
- add_settings_field( 'iub_parse', __( 'Script blocking', 'iubenda' ), array( $this, 'iub_parse' ), 'iubenda_cookie_law_solution', 'iubenda_cookie_law_solution' );
128
- add_settings_field( 'iub_custom_scripts', __( 'Custom scripts', 'iubenda' ), array( $this, 'iub_custom_scripts' ), 'iubenda_cookie_law_solution', 'iubenda_cookie_law_solution' );
129
- add_settings_field( 'iub_ctype', __( 'Content type', 'iubenda' ), array( $this, 'iub_ctype' ), 'iubenda_cookie_law_solution', 'iubenda_cookie_law_solution' );
130
- add_settings_field( 'iub_output_feed', __( 'RSS feed', 'iubenda' ), array( $this, 'iub_output_feed' ), 'iubenda_cookie_law_solution', 'iubenda_cookie_law_solution' );
131
- add_settings_field( 'iub_output_post', __( 'POST requests', 'iubenda' ), array( $this, 'iub_output_post' ), 'iubenda_cookie_law_solution', 'iubenda_cookie_law_solution' );
132
- add_settings_field( 'iub_menu_position', __( 'Menu position', 'iubenda' ), array( $this, 'iub_menu_position' ), 'iubenda_cookie_law_solution', 'iubenda_cookie_law_solution' );
133
- add_settings_field( 'iub_deactivation', __( 'Deactivation', 'iubenda' ), array( $this, 'iub_deactivation' ), 'iubenda_cookie_law_solution', 'iubenda_cookie_law_solution' );
134
-
135
- // forms list
136
- if ( ! in_array( $this->action, array( 'save', 'edit' ) ) ) {
137
- register_setting( 'iubenda_consent_solution', 'iubenda_consent_solution', array( $this, 'save_consent_options' ) );
138
- add_settings_section( 'iubenda_consent_solution', __( 'Forms', 'iubenda' ), '', 'iubenda_consent_solution' );
139
- add_settings_field( 'iub_public_api_key', __( 'Public Api Key', 'iubenda' ), array( $this, 'iub_public_api_key' ), 'iubenda_consent_solution', 'iubenda_consent_solution' );
140
- // only if api key is given
141
- if ( ! empty( iubenda()->options['cons']['public_api_key'] ) )
142
- add_settings_section( 'iubenda_consent_forms', __( 'Field Mapping', 'iubenda' ), array( $this, 'iubenda_consent_forms' ), 'iubenda_consent_solution' );
143
- // single form
144
- } else {
145
- register_setting( 'iubenda_consent_solution', 'iubenda_consent_forms' );
146
- add_settings_section( 'iubenda_consent_form', __( 'Field Mapping', 'iubenda' ), array( $this, 'iubenda_consent_form' ), 'iubenda_consent_solution' );
147
- }
148
- }
149
-
150
- /**
151
- * Display errors and notices.
152
- *
153
- * @global string $pagenow
154
- */
155
- public function settings_errors() {
156
- global $pagenow;
157
-
158
- // force display notices in top menu settings page
159
- if ( $pagenow == 'options-general.php' )
160
- return;
161
-
162
- $tab_key = ! empty( $_GET['tab'] ) ? esc_attr( $_GET['tab'] ) : 'cs';
163
-
164
- settings_errors( "{$tab_key}_settings_errors" );
165
- }
166
-
167
- /**
168
- * Add submenu.
169
- *
170
- * @return void
171
- */
172
- public function admin_menu_options() {
173
- if ( iubenda()->options['cs']['menu_position'] === 'submenu' ) {
174
- // sub menu
175
- add_submenu_page(
176
- 'options-general.php', 'iubenda', 'iubenda', apply_filters( 'iubenda_cookie_law_cap', 'manage_options' ), 'iubenda', array( $this, 'options_page' )
177
- );
178
- } else {
179
- // top menu
180
- add_menu_page(
181
- 'iubenda', 'iubenda', apply_filters( 'iubenda_cookie_law_cap', 'manage_options' ), 'iubenda', array( $this, 'options_page' ), 'none'
182
- );
183
- add_submenu_page( 'iubenda', __( 'Cookie Solution', 'iubenda' ), __( 'Cookie Solution', 'iubenda' ), apply_filters( 'iubenda_cookie_law_cap', 'manage_options' ), 'iubenda', array( $this, 'options_page' ) );
184
- add_submenu_page( 'iubenda', __( 'Consent Solution', 'iubenda' ), __( 'Consent Solution', 'iubenda' ), apply_filters( 'iubenda_cookie_law_cap', 'manage_options' ), 'iubenda&tab=cons', array( $this, 'options_page' ) );
185
- }
186
- }
187
-
188
- /**
189
- * Load admin scripts and styles.
190
- *
191
- * @param string $page
192
- * @return void
193
- */
194
- public function admin_enqueue_scripts( $page ) {
195
- wp_enqueue_style( 'iubenda-admin', IUBENDA_PLUGIN_URL . '/css/admin.css' );
196
-
197
- if ( ! in_array( $page, array( 'toplevel_page_iubenda', 'settings_page_iubenda' ) ) )
198
- return;
199
-
200
- wp_enqueue_script(
201
- 'iubenda-admin', IUBENDA_PLUGIN_URL . '/js/admin.js', array( 'jquery' )
202
- );
203
-
204
- $args = array(
205
- 'formId' => 0,
206
- 'deleteForm' => __( 'Are you sure you want to delete this form?', 'iubenda' )
207
- );
208
-
209
- // get form data on edit screen
210
- if ( in_array( $this->action, array( 'edit' ) ) ) {
211
- $form_id = ! empty( $_GET['form_id'] ) ? absint( $_GET['form_id'] ) : 0;
212
- $form = ! empty( $form_id ) ? iubenda()->forms->get_form( $form_id ) : array();
213
-
214
- $args['formId'] = $form_id;
215
- }
216
-
217
- wp_localize_script(
218
- 'iubenda-admin',
219
- 'iubAdminArgs',
220
- json_encode( $args )
221
- );
222
- }
223
-
224
- /**
225
- * Load admin style inline, for menu icon only.
226
- *
227
- * @return mixed
228
- */
229
- public function admin_print_styles() {
230
- echo '
231
- <style>
232
- a.toplevel_page_iubenda .wp-menu-image {
233
- background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj48c3ZnIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHZpZXdCb3g9IjAgMCAyMzIgNTAzIiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHhtbDpzcGFjZT0icHJlc2VydmUiIHhtbG5zOnNlcmlmPSJodHRwOi8vd3d3LnNlcmlmLmNvbS8iIHN0eWxlPSJmaWxsLXJ1bGU6ZXZlbm9kZDtjbGlwLXJ1bGU6ZXZlbm9kZDtzdHJva2UtbGluZWpvaW46cm91bmQ7c3Ryb2tlLW1pdGVybGltaXQ6MS40MTQyMTsiPiAgICA8ZyB0cmFuc2Zvcm09Im1hdHJpeCgxLDAsMCwxLDEzNi4yNDcsMjY4LjgzMSkiPiAgICAgICAgPHBhdGggZD0iTTAsLTM1LjgxTC0zNi4zLDAuNDg5TC0zNi4zLDE0MC45NzhMMCwxNDAuOTc4TDAsLTM1LjgxWk0tMjAuOTM4LC0xMjkuODAyQy02LjI4NywtMTI5LjgwMiA1LjU4NywtMTQxLjU2NSA1LjU4NywtMTU2LjA2QzUuNTg3LC0xNzAuNTU2IC02LjI4NywtMTgyLjMwOCAtMjAuOTM4LC0xODIuMzA4Qy0zNS42LC0xODIuMzA4IC00Ny40NzQsLTE3MC41NTYgLTQ3LjQ3NCwtMTU2LjA2Qy00Ny40NzQsLTE0MS41NjUgLTM1LjYsLTEyOS44MDIgLTIwLjkzOCwtMTI5LjgwMk04OS4zNiwtMTU0LjQxNkM4OS4zNiwtMTI3LjgyNSA3OS41NzUsLTEwMy40OTkgNjMuMjY5LC04NC42NzJMODYuNjk0LDIyNi42MjhMLTEyMi43MjgsMjI2LjYyOEwtMTAwLjAyNCwtNzkuMjI5Qy0xMTkuMzUxLC05OC42NjggLTEzMS4yNDcsLTEyNS4xNTkgLTEzMS4yNDcsLTE1NC40MTZDLTEzMS4yNDcsLTIxNC4wODYgLTgxLjg3NCwtMjYyLjQzOCAtMjAuOTM4LC0yNjIuNDM4QzM5Ljk5OSwtMjYyLjQzOCA4OS4zNiwtMjE0LjA4NiA4OS4zNiwtMTU0LjQxNiIgc3R5bGU9ImZpbGw6d2hpdGU7ZmlsbC1ydWxlOm5vbnplcm87Ii8+ICAgIDwvZz48L3N2Zz4=);
234
- background-position: center center;
235
- background-repeat: no-repeat;
236
- background-size: 7px auto;
237
- }
238
- </style>
239
- ';
240
- }
241
-
242
- /**
243
- * Highlight comments cookies opt-in checkbox option.
244
- *
245
- * @return mixed
246
- */
247
- public function admin_footer() {
248
- if ( ! empty( $_GET['iub-highlight'] ) ) {
249
- echo '
250
- <style>
251
- label[for=show_comments_cookies_opt_in] {
252
- border: 1px dashed red;
253
- }
254
- </style>
255
- ';
256
- }
257
- }
258
-
259
- /**
260
- * Redirect to the correct urle after switching menu position.
261
- *
262
- * @global string $pagenow
263
- * @return void
264
- */
265
- public function admin_page_redirect() {
266
- if ( ! empty( $_GET['settings-updated'] ) && ! empty( $_GET['page'] ) && in_array( $_GET['page'], array( 'iubenda' ) ) ) {
267
- global $pagenow;
268
-
269
- // no redirect by default
270
- $redirect_to = false;
271
-
272
- if ( iubenda()->options['cs']['menu_position'] === 'submenu' && $pagenow === 'admin.php' ) {
273
- // sub menu
274
- $redirect_to = admin_url( 'options-general.php?page=iubenda' );
275
- } elseif ( iubenda()->options['cs']['menu_position'] === 'topmenu' && $pagenow === 'options-general.php' ) {
276
- // top menu
277
- $redirect_to = admin_url( 'admin.php?page=iubenda' );
278
- }
279
-
280
- if ( $redirect_to ) {
281
- // make sure it's current host location
282
- wp_safe_redirect( add_query_arg( 'settings-updated', true, $redirect_to ) );
283
- exit;
284
- }
285
- }
286
- }
287
-
288
- /**
289
- * Perform show notice on plugin installation/upgrade.
290
- *
291
- * @return void
292
- */
293
- public function maybe_show_notice() {
294
- if ( ! current_user_can( 'install_plugins' ) )
295
- return;
296
-
297
- $current_update = 1;
298
- $activation = (array) get_option( 'iubenda_activation_data', iubenda()->activation );
299
-
300
- // delete_option( 'iubenda_activation_data' );
301
- // echo '<pre>'; print_r( $activation ); echo '</pre>'; exit;
302
-
303
- // get current time
304
- $current_time = time();
305
-
306
- if ( $activation['update_version'] < $current_update ) {
307
- // check version, if update ver is lower than plugin ver, set update notice to true
308
- $activation = array_merge( $activation, array( 'update_version' => $current_update, 'update_notice' => true ) );
309
-
310
- // set activation date if not set
311
- if ( $activation['update_date'] == false )
312
- $activation = array_merge( $activation, array( 'update_date' => $current_time ) );
313
-
314
- update_option( 'iubenda_activation_data', $activation );
315
- }
316
-
317
- // display current version notice
318
- if ( $activation['update_notice'] === true ) {
319
- // include notice js, only if needed
320
- add_action( 'admin_print_scripts', array( $this, 'admin_inline_js' ), 999 );
321
-
322
- // get activation date
323
- $activation_date = $activation['update_date'];
324
-
325
- // set delay in seconds
326
- $delay = WEEK_IN_SECONDS * 2;
327
-
328
- if ( (int) $activation['update_delay_date'] === 0 ) {
329
- if ( $activation_date + $delay > $current_time )
330
- $activation['update_delay_date'] = $activation_date + $delay;
331
- else
332
- $activation['update_delay_date'] = $current_time;
333
-
334
- update_option( 'iubenda_activation_data', $activation );
335
- }
336
-
337
- if ( ( ! empty( $activation['update_delay_date'] ) ? (int) $activation['update_delay_date'] : $current_time ) <= $current_time ) {
338
- // add notice
339
- add_action( 'admin_notices', array( $this, 'show_notice' ) );
340
- }
341
- }
342
- }
343
-
344
- /**
345
- * Display admin notices at iubenda settings.
346
- */
347
- public function show_notice() {
348
- global $pagenow;
349
-
350
- $display = true;
351
- /*
352
- $page = isset( $_GET['page'] ) ? esc_attr( $_GET['page'] ) : '';
353
-
354
- if ( iubenda()->options['cs']['menu_position'] === 'submenu' && $page === 'iubenda' ) {
355
- $display = true;
356
- } elseif ( iubenda()->options['cs']['menu_position'] === 'topmenu' && $page === 'iubenda' ) {
357
- $display = true;
358
- }
359
- */
360
- ?>
361
- <?php if ( $display ) { ?>
362
- <div class="iubenda-notice notice is-dismissible">
363
- <div>
364
- <p class="step-1">
365
- <span class="notice-question"><?php _e( 'Enjoying the iubenda Cookie & Consent Solution Plugin?', 'iubenda' ); ?></span>
366
- <span class="notice-reply">
367
- <a href="#" class="reply-yes"><?php _e( 'Yes', 'iubenda' ); ?></a>
368
- <a href="#" class="reply-no"><?php _e( 'No', 'iubenda' ); ?></a>
369
- </span>
370
- </p>
371
- <p class="step-2 step-yes">
372
- <span class="notice-question"><?php _e( "Whew, what a relief!? We've worked countless hours to make this plugin as useful as possible - so we're pretty happy that you're enjoying it. While you here, would you mind leaving us a 5 star rating? It would really help us out.", 'iubenda' ); ?></span>
373
- <span class="notice-reply">
374
- <a href="https://wordpress.org/support/plugin/iubenda-cookie-law-solution/reviews/?filter=5" target="_blank" class="reply-yes"><?php _e( 'Sure!', 'iubenda' ); ?></a>
375
- <a href="javascript:void(0)" class="reply-no"><?php _e( 'No thanks', 'iubenda' ); ?></a>
376
- </span>
377
- </p>
378
- <p class="step-2 step-no">
379
- <span class="notice-question"><?php _e( "We're sorry to hear that. Would you mind giving us some feedback?", 'iubenda' ); ?></span>
380
- <span class="notice-reply">
381
- <a href="https://iubenda.typeform.com/to/BXuSMZ" target="_blank" class="reply-yes"><?php _e( 'Ok sure!', 'iubenda' ); ?></a>
382
- <a href="javascript:void(0)" class="reply-no"><?php _e( 'No thanks', 'iubenda' ); ?></a>
383
- </span>
384
- </p>
385
- </div>
386
- </div>
387
- <?php } ?>
388
- <?php
389
- }
390
-
391
- /**
392
- * Print admin scripts.
393
- *
394
- * @return void
395
- */
396
- public function admin_inline_js() {
397
- if ( ! current_user_can( 'install_plugins' ) )
398
- return;
399
-
400
- $delay = MONTH_IN_SECONDS * 6;
401
- ?>
402
- <script type="text/javascript">
403
- ( function ( $ ) {
404
- $( document ).ready( function () {
405
- // step 1
406
- $( '.iubenda-notice .step-1 a' ).on( 'click', function ( e ) {
407
- e.preventDefault();
408
-
409
- $( '.iubenda-notice .step-1' ).slideUp( 'fast' );
410
-
411
- if ( $( e.target ).hasClass( 'reply-yes' ) ) {
412
- $( '.iubenda-notice .step-2.step-yes' ).slideDown( 'fast' );
413
- } else {
414
- $( '.iubenda-notice .step-2.step-no' ).slideDown( 'fast' );
415
- };
416
- } );
417
- // step 2
418
- $( '.iubenda-notice.is-dismissible' ).on( 'click', '.notice-dismiss, .step-2 a', function ( e ) {
419
- // console.log( $( e ) );
420
-
421
- var delay = <?php echo $delay; ?>;
422
-
423
- if ( $( e.target ).hasClass( 'reply-yes' ) ) {
424
- delay = 0;
425
- }
426
-
427
- $.post( ajaxurl, {
428
- action: 'iubenda_dismiss_notice',
429
- delay: delay,
430
- url: '<?php echo admin_url( 'admin-ajax.php' ); ?>',
431
- iubenda_nonce: '<?php echo wp_create_nonce( 'iubenda_dismiss_notice' ); ?>'
432
- } );
433
-
434
- $( e.delegateTarget ).slideUp( 'fast' );
435
- } );
436
- } );
437
- } )( jQuery );
438
- </script>
439
- <?php
440
- }
441
-
442
- /**
443
- * Dismiss notice.
444
- *
445
- * @return void
446
- */
447
- public function dismiss_notice() {
448
- $result = false;
449
-
450
- if ( ! current_user_can( 'install_plugins' ) )
451
- return $result;
452
-
453
- $nonce = wp_verify_nonce( $_REQUEST['iubenda_nonce'], 'iubenda_dismiss_notice' );
454
-
455
- if ( $nonce ) {
456
- $delay = ! empty( $_REQUEST['delay'] ) ? absint( $_REQUEST['delay'] ) : 0;
457
- $activation = (array) get_option( 'iubenda_activation_data', iubenda()->activation );
458
-
459
- // delay notice
460
- if ( $delay > 0 ) {
461
- $activation = array_merge( $activation, array( 'update_delay_date' => time() + $delay ) );
462
- // hide notice permanently
463
- } else {
464
- $activation = array_merge( $activation, array( 'update_delay_date' => 0, 'update_notice' => false ) );
465
- }
466
-
467
- // update activation options
468
- $result = update_option( 'iubenda_activation_data', $activation );
469
- }
470
-
471
- echo json_encode( $result );
472
- exit;
473
- }
474
-
475
- /**
476
- * Plugin options migration for versions < 1.14.0
477
- *
478
- * @return void
479
- */
480
- public function update_plugin() {
481
- if ( ! current_user_can( 'install_plugins' ) )
482
- return;
483
-
484
- $db_version = get_option( 'iubenda_cookie_law_version' );
485
- $db_version = ! $db_version ? '1.13.0' : $db_version;
486
-
487
- if ( $db_version != false ) {
488
- if ( version_compare( $db_version, '1.14.0', '<' ) ) {
489
- $options = array();
490
-
491
- $old_new = array(
492
- 'iubenda_parse' => 'parse',
493
- 'skip_parsing' => 'skip_parsing',
494
- 'iubenda_ctype' => 'ctype',
495
- 'iubenda_parse' => 'parse',
496
- 'parser_engine' => 'parser_engine',
497
- 'iubenda_output_feed' => 'output_feed',
498
- 'iubenda-code-default' => 'code_default',
499
- 'default_skip_parsing' => '',
500
- 'default_iubendactype' => '',
501
- 'default_iubendaparse' => '',
502
- 'default_parser_engine' => '',
503
- 'iub_code' => '',
504
- );
505
-
506
- foreach ( $old_new as $old => $new ) {
507
- if ( $new ) {
508
- $options[$new] = get_option( $old );
509
- }
510
- delete_option( $old );
511
- }
512
-
513
- // multilang support
514
- if ( ! empty( iubenda()->languages ) ) {
515
- foreach ( iubenda()->languages as $lang_id => $lang_name ) {
516
- $code = get_option( 'iubenda-code-' . $lang_id );
517
-
518
- if ( ! empty( $code ) ) {
519
- $options['code_' . $lang_id] = $code;
520
-
521
- delete_option( 'iubenda-code-' . $lang_id );
522
- }
523
- }
524
- }
525
-
526
- add_option( 'iubenda_cookie_law_solution', $options, '', 'no' );
527
- add_option( 'iubenda_cookie_law_version', iubenda()->version, '', 'no' );
528
- }
529
- }
530
- }
531
-
532
- /**
533
- * Load admin options page.
534
- *
535
- * @return void
536
- */
537
- public function options_page() {
538
- global $pagenow;
539
-
540
- if ( ! current_user_can( apply_filters( 'iubenda_cookie_law_cap', 'manage_options' ) ) ) {
541
- wp_die( __( "You don't have permission to access this page.", 'iubenda' ) );
542
- }
543
-
544
- $tab_key = ! empty( $_GET['tab'] ) ? esc_attr( $_GET['tab'] ) : 'cs';
545
-
546
- // get redirect url
547
- if ( iubenda()->options['cs']['menu_position'] === 'submenu' && $pagenow === 'admin.php' ) {
548
- // sub menu
549
- $redirect_to = admin_url( 'options-general.php?page=iubenda&tab=' . $tab_key );
550
- } else {
551
- // top menu
552
- $redirect_to = admin_url( 'admin.php?page=iubenda&tab=' . $tab_key );
553
- }
554
- ?>
555
- <div class="wrap">
556
-
557
- <div id="iubenda-header">
558
- <?php
559
- echo '
560
- <a class="iubenda-link" href="http://iubenda.com" title="iubenda" title="_blank">
561
- <img id="iubenda-logo" alt="iubenda logo" width="300" height="90" src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgNjM3LjggMjgzLjUiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDYzNy44IDI4My41OyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHN0eWxlIHR5cGU9InRleHQvY3NzIj4uc3Qwe2ZpbGw6IzFDQzY5MTt9LnN0MXtmaWxsOiM1MTUyNTQ7fTwvc3R5bGU+PHBhdGggY2xhc3M9InN0MCIgZD0iTTE3OC45LDk5LjljMCw4LjItMywxNS42LTgsMjEuNGw3LjIsOTUuNGgtNjQuMmw3LTkzLjhjLTUuOS02LTkuNi0xNC4xLTkuNi0yMy4xYzAtMTguMywxNS4xLTMzLjEsMzMuOC0zMy4xUzE3OC45LDgxLjYsMTc4LjksOTkuOSBNMTQ1LjEsMTA3LjRjNC41LDAsOC4xLTMuNiw4LjEtOC4xcy0zLjYtOC04LjEtOGMtNC41LDAtOC4xLDMuNi04LjEsOFMxNDAuNiwxMDcuNCwxNDUuMSwxMDcuNCBNMTUxLjUsMTM2LjJsLTExLjEsMTEuMXY0My4xaDExLjFWMTM2LjJ6Ii8+PHBhdGggY2xhc3M9InN0MSIgZD0iTTI2NS40LDE3OC42Yy0yLjMsMS4yLTQuNywxLjgtNy4yLDEuOGMtMi44LDAtNS4zLTAuOC03LjQtMi40Yy0yLjEtMS42LTMuNS0zLjctNC4zLTYuMmMtMC44LTIuNS0xLjItNi4xLTEuMi0xMC44di0xOC4yYzAsMCwwLTAuOSwwLTIuOGMwLTAuNSwwLTIuOC0xLjUtMy41Yy0wLjItMC4xLTAuNi0wLjItMS4yLTAuM2MtMC40LDAtMC44LTAuNC0wLjgtMC44bDAtMi40YzAtMC41LDAuNC0wLjksMC44LTAuOWg5LjNjMS4zLDAsMi40LDEuMSwyLjQsMi40VjE0N2wwLDE1LjVjMCw0LjYsMC44LDcuNywyLjUsOS4xYzEuNiwxLjUsMy42LDIuMiw1LjksMi4yYzEuNiwwLDMuNC0wLjUsNS40LTEuNWMyLTEsNS4zLTIuOCw4LjEtNS42bDAtMi40bDAtMjIuMlYxNDBjMC0wLjUsMC0yLjgtMS40LTMuNWMtMC4yLTAuMS0wLjYtMC4yLTEuMS0wLjNjLTAuNC0wLjEtMC44LTAuNC0wLjgtMC44bDAtMi40YzAtMC41LDAuNC0wLjksMC45LTAuOWg5LjJjMS4zLDAsMi40LDEuMSwyLjQsMi40djhjMCwwLjEsMCwwLjEsMCwwLjJ2MTYuNmMwLDMuOCwwLDcuNCwwLDEwLjZjMCwwLjcsMCwxLjIsMCwxLjJjMCwwLjUtMC4xLDMuMSwxLjQsMy44YzAuMiwwLjEsMC42LDAuMiwxLjIsMC4zYzAuNCwwLDAuOCwwLjQsMC44LDAuOGwwLDIuNGMwLDAuNS0wLjQsMC44LTAuOSwwLjloLTkuMmMtMS4zLDAtMi40LTEuMS0yLjQtMi40bDAtNC41bDAtMi41QzI3MS45LDE3NC41LDI2Ny43LDE3Ny40LDI2NS40LDE3OC42Ii8+PHBhdGggY2xhc3M9InN0MSIgZD0iTTMwOS4yLDE3NmMxLjksMC45LDMuOSwxLjMsNiwxLjNjMy4yLDAsNi4zLTEuNyw5LTUuMmMyLjgtMy41LDQuMi04LjUsNC4yLTE1LjJjMC02LjEtMS40LTEwLjgtNC4yLTE0LjFjLTIuOC0zLjMtNi00LjktOS41LTQuOWMtMS45LDAtMy44LDAuNS01LjcsMS40Yy0xLjIsMC42LTIuOCwxLjgtNC43LDMuNGMtMC41LDAuNS0wLjgsMS4xLTAuOCwxLjhWMTcxYzAsMC43LDAuMywxLjQsMC44LDEuOEMzMDYsMTc0LjIsMzA3LjYsMTc1LjMsMzA5LjIsMTc2IE0yOTQuOCwxMThjMC0wLjUsMC0yLjctMS40LTMuNGMtMC4yLTAuMS0wLjMtMC4xLTAuNi0wLjJjLTAuNC0wLjEtMC42LTAuNC0wLjYtMC44bDAtMi4zYzAtMC41LDAuNC0wLjgsMC45LTAuOWgxLjhoNi41YzEuMywwLDIuMywxLDIuMywyLjNsMCwxMnYxNS40YzQuNy02LjQsOS44LTkuNiwxNS4zLTkuNmM1LDAsOS40LDIuMSwxMy4xLDYuM2MzLjcsNC4yLDUuNiw5LjksNS42LDE3LjJjMCw4LjUtMi45LDE1LjMtOC42LDIwLjVjLTQuOSw0LjQtMTAuNSw2LjctMTYuNSw2LjdjLTIuOCwwLTUuNy0wLjUtOC43LTEuNWMtMi41LTAuOS01LjEtMi4xLTcuNy0zLjdjLTAuOC0wLjUtMS4zLTEuNC0xLjMtMi40di00NmMwLTAuOSwwLTIsMC0zLjNMMjk0LjgsMTE4eiIvPjxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik0zODkuMywxNzkuMWMtMC41LDAtMC45LTAuNC0wLjktMC45bDAtMi4zYzAtMC40LDAuMy0wLjgsMC43LTAuOGMwLjUtMC4xLDAuOC0wLjEsMS0wLjJjMS40LTAuNywxLjQtMi45LDEuNC0zLjR2LTIuN2MwLDAsMC01LjgsMC0xNy41YzAtMS45LDAtMy44LDAuMS01LjVsMC00LjZjMC0wLjUsMC0xLDAtMS41YzAtMC42LDAtMi44LTEuNC0zLjVjLTAuMS0wLjEtMC4zLTAuMS0wLjUtMC4yYy0wLjQtMC4xLTAuNi0wLjQtMC42LTAuOGwwLTIuM2MwLTAuNSwwLjQtMC44LDAuOS0wLjloOC4xYzEuMywwLDIuMywxLDIuMywyLjN2My40YzAsMCwwLDAuNiwwLDEuOGMwLDAuMywwLjIsMC42LDAuNiwwLjZjMC4yLDAsMC4zLTAuMSwwLjQtMC4yYzUuNC01LjksMTIuMy04LjgsMTcuMi04LjhjMi43LDAsNSwwLjYsNi45LDEuOWMxLjksMS4zLDMuNCwzLjQsNC42LDYuM2MwLjgsMi4xLDEuMiw1LjIsMS4yLDkuNHYxNi41bDAsNi4zYzAsMC41LDAsMi43LDEuNCwzLjRjMC4yLDAuMSwwLjQsMC4yLDAuOCwwLjJjMC40LDAuMSwwLjcsMC40LDAuNywwLjhsMCwyLjNjMCwwLjUtMC40LDAuOC0wLjgsMC45Yy0wLjgsMC0xLjUsMC0yLDBoLTYuNWMtMC4xLDAtMC4zLDAtMC40LDBoLTMuMWMtMS4xLDAtMi0wLjktMi0yYzAtMSwwLjctMS45LDEuNi0yLjJjMC4xLDAsMC4xLDAsMC4yLTAuMWMxLTAuNSwxLjMtMS44LDEuNC0yLjd2LTcuNGwwLTE1LjJjMC00LjMtMC42LTcuNC0xLjctOS4zYy0xLjItMS45LTMuMS0yLjktNS44LTIuOWMtNC4yLDAtMTAuMywyLjItMTQuNCw2Ljd2MjAuOHYwLjNsMCw2LjRjMCwwLjUsMCwyLjgsMS40LDMuNWMwLjEsMCwwLjEsMCwwLjIsMC4xYzEsMC4zLDEuNiwxLjIsMS42LDIuMmMwLDEuMS0wLjksMi0yLDJIMzk0QzM5NCwxNzkuMSwzOTIuNCwxNzkuMSwzODkuMywxNzkuMSIvPjxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik01MTUsMTUzLjRjLTYuNiwxLjMtMTAuNCwyLjItMTEuNCwyLjVjLTMuNywxLjItNi42LDIuNi02LjgsOC43Yy0wLjEsMi41LDAuOCw0LjcsMi4zLDYuM2MxLjUsMS43LDMuMywyLjUsNS4zLDIuNWMyLjUsMCw1LjctMS44LDkuNi00LjhjMC43LTAuNSwxLjEtMS4zLDEuMS0yLjJWMTUzLjR6IE01MjMuOCwxNzAuOGMwLDAuMSwwLDAuMiwwLDAuMmMwLDAuMiwwLDAuMywwLDAuNGMwLjEsMS40LDAuNiwyLjQsMS40LDIuOGMwLjIsMC4xLDAuNCwwLjIsMC42LDAuMmMwLjQsMC4xLDAuNywwLjQsMC43LDAuOGwwLDIuNGMwLDAuNS0wLjQsMC44LTAuOSwwLjloLTguM2MtMS4zLDAtMi4zLTEtMi4zLTIuM3YtNC41Yy01LDMuOS04LjIsNi4xLTkuNSw2LjdjLTEuOSwwLjktNCwxLjMtNi4xLDEuM2MtMy40LDAtNi4yLTEuMi04LjQtMy40Yy0yLjItMi4zLTMuMy01LjMtMy4zLTkuMWMwLTIuNCwwLjUtNC40LDEuNi02LjJjMS41LTIuNCwzLjctNS4yLDcuNi02LjhjNC0xLjYsNy4zLTIsMTgtNC40YzAtMC4zLDAtNCwwLTQuM2MwLTQuNS0wLjgtOS4yLTguNC04LjdjLTUuMywwLjMtMTAuMiwyLTE0LjcsNWMtMC40LDAuMy0wLjksMC4yLTEuMi0wLjJjLTAuMS0wLjEtMC4xLTAuMy0wLjEtMC41di0yLjhjMC0xLjUsMC4zLTIuNCwwLjktMi45YzMuMS0yLjUsMTAuOS01LjUsMTguNS01YzguNCwwLjYsMTEuNCw0LDEyLjksOS4zYzAuNSwxLjYsMSwyLjgsMSw3LjV2MTQuNWMwLDIsMCw0LDAsNS44VjE3MC44eiIvPjxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik00NjUuNCwxMzcuOGMtMS43LTEtMy40LTEuNS01LTEuNWMtMywwLTUuOCwxLjMtOC4zLDMuOGMtMi43LDIuOC00LjYsNi41LTQuNiwxMy41YzAsNywxLjUsMTIuNCw0LjYsMTYuMmMzLDMuNyw2LjQsNS42LDEwLjIsNS42YzIuNywwLDUuMy0xLjEsNy44LTMuNGMwLjktMC44LDEuNC0xLjksMS40LTN2LTIwLjhDNDcxLjQsMTQzLjksNDY5LjEsMTQwLDQ2NS40LDEzNy44IE00ODEuMywxNzQuNmMwLjEsMC4xLDAuMywwLjEsMC41LDAuMmMwLjQsMC4xLDAuNiwwLjQsMC42LDAuOGwwLDIuM2MwLDAuNS0wLjQsMC44LTAuOSwwLjloLThjLTEuMiwwLTIuMy0xLTIuMy0yLjJ2LTIuMmMtMi4zLDIuNC00LjYsNC4yLTYuOCw1LjNjLTIuMiwxLjEtNC42LDEuNi03LjEsMS42Yy01LjIsMC05LjctMi4yLTEzLjYtNi42Yy0zLjktNC40LTUuOC0xMC01LjgtMTYuOXMyLjEtMTMuMSw2LjQtMTguOGM0LjMtNS43LDkuOC04LjUsMTYuNS04LjVjNC4yLDAsNy42LDEuMywxMC40LDR2LTE2LjdjMC0wLjUsMC0yLjctMS40LTMuNGMtMC4xLTAuMS0wLjMtMC4xLTAuNS0wLjJjLTAuNC0wLjEtMC42LTAuNC0wLjYtMC44bDAtMi40YzAtMC41LDAuNC0wLjksMC45LTAuOWg3LjljMS4yLDAsMi4zLDEsMi4zLDIuMnY1OC45QzQ3OS45LDE3MS44LDQ3OS45LDE3My45LDQ4MS4zLDE3NC42Ii8+PHBhdGggY2xhc3M9InN0MSIgZD0iTTM1MCwxNTAuMmMwLDAuMSwwLDAuMywwLjEsMC4zYzAuMSwwLjEsMC4yLDAuMSwwLjQsMC4xaDIzLjljMC4zLDAsMC41LTAuMiwwLjUtMC40YzAuMy0yLjUsMC40LTctMy4zLTEwLjhjLTEuOC0xLjktNC4xLTIuOC04LjMtMi44QzM1NS43LDEzNi42LDM1MC44LDE0My45LDM1MCwxNTAuMiBNMzQ3LjUsMTc0LjljLTMuOS00LjMtNS45LTExLjMtNS45LTE4LjJjMC03LjMsMi4zLTEzLjksNi40LTE4LjdjNC4zLTUsMTAuMi03LjcsMTcuMS03LjdjNS44LDAsMTAuMiwyLDEzLjIsNS44YzIuNywzLjYsNC4xLDguOCw0LjEsMTUuNGMwLDAuOCwwLDEuOS0wLjEsMy4zYy0wLjEsMC45LTAuOCwxLjYtMS43LDEuNmgtMjkuOGMtMC4xLDAtMC4zLDAuMS0wLjQsMC4xYy0wLjEsMC4xLTAuMSwwLjItMC4xLDAuNGMwLjEsNS40LDEuOCwxMCw1LDEzLjJjMy4xLDMuMiw3LjQsNC45LDEyLjQsNC45YzMuNywwLDguNi0xLDEyLjQtMi4xYzAuNS0wLjIsMS4xLDAuMSwxLjMsMC43YzAuMSwwLjIsMC4xLDAuNCwwLDAuNWwtMC41LDEuOWMtMC4yLDAuNy0wLjcsMS4zLTEuMywxLjZjLTMuNywxLjgtOS4zLDMuNS0xNSwzLjVDMzU3LjYsMTgxLjIsMzUxLjYsMTc5LjUsMzQ3LjUsMTc0LjkiLz48cGF0aCBjbGFzcz0ic3QxIiBkPSJNMjMxLjEsMTM1Ljl2MzYuOWMwLDEsMC42LDEuOSwxLjQsMi4zYzAuOSwwLjQsMS40LDEuMywxLjQsMi4zdjAuN2MwLDAuOC0wLjYsMS40LTEuNCwxLjRIMjIwYy0wLjgsMC0xLjQtMC42LTEuNC0xLjR2LTAuN2MwLTEsMC42LTEuOSwxLjQtMi4zYzAuOS0wLjQsMS40LTEuMywxLjQtMi4zdi0zNS43YzAtMC41LTAuNC0wLjktMC45LTAuOXMtMC45LTAuNC0wLjktMC45di0xLjJjMC0xLjIsMC45LTIuMSwyLjEtMi4xaDUuNkMyMjkuNCwxMzIsMjMxLjEsMTMzLjcsMjMxLjEsMTM1LjkiLz48cGF0aCBjbGFzcz0ic3QxIiBkPSJNMjI2LjMsMTEwLjhjMy4zLDAsNiwyLjcsNiw1LjljMCwzLjMtMi43LDUuOS02LDUuOXMtNi0yLjctNi01LjlDMjIwLjMsMTEzLjUsMjIzLDExMC44LDIyNi4zLDExMC44Ii8+PC9zdmc+"/>
562
- </a>';
563
-
564
- if ( $tab_key === 'cs' ) {
565
- echo '
566
- <p class="iubenda-text">
567
- ' . __( "This plugin is the easiest and most comprehensive way to adapt your WordPress site to the ePrivacy (EU Cookie Law). Upon your users' first visit, the plugin will take care of collecting their consent, blocking the most popular cookie-scripts and subsequently reactivating these scripts as soon as consent is provided. The basic settings include obtaining consent by a simple scroll action (the most effective method) and script reactivation without refreshing the page (asynchronous script reactivation).", 'iubenda' ) . '
568
- </p>
569
- <p class="iubenda-text">
570
- <span class="iubenda-title">' . __( "Does the Cookie Solution support IAB's Transparency and Consent Framework?", 'iubenda' ) . '</span><br />
571
- ' . sprintf( __( "Yes it does. You can read more about it <a href=\"%s\" class=\"iubenda-url\" target=\"_blank\">here.</a>", 'iubenda' ), $this->links['iab'] ) . '
572
- </p>
573
- <p class="iubenda-text">
574
- <span class="iubenda-title">' . __( "Would you like to know more about the cookie law?", 'iubenda' ) . '</span><br />
575
- ' . sprintf( __( "Read our <a href=\"%s\" class=\"iubenda-url\" target=\"_blank\">complete guide to the cookie law.</a>", 'iubenda' ), $this->links['guide'] ) . '
576
- </p>
577
- <p class="iubenda-text">
578
- <span class="iubenda-title">' . __( "What is the full functionality of the plugin?", 'iubenda' ) . '</span><br />
579
- ' . sprintf( __( "Visit our <a href=\"%s\" class=\"iubenda-url\" target=\"_blank\">plugin page.</a>", 'iubenda' ), $this->links['plugin_page'] ) . '
580
- </p>
581
- <p class="iubenda-text">
582
- <span class="iubenda-title">' . __( "Enter the iubenda code for the Cookie Solution below.", 'iubenda' ) . '</span><br />
583
- ' . sprintf( __( "In order to run the plugin, you need to enter the iubenda code that activates the cookie law banner and the cookie policy in the form below. This code can be generated on www.iubenda.com, following <a href=\"%s\" class=\"iubenda-url\" target=\"_blank\">this guide.</a>", 'iubenda' ), $this->links['generating_code'] ) . '
584
- </p>';
585
- } else {
586
- echo '
587
- <p class="iubenda-text">
588
- ' . __( 'Maintaining comprehensive records of consent is a vital part of privacy compliance in general but is specifically required under the GDPR. These records should include a way of identifying the user, store proof of consent, record of the consenting action, and the legal documents available to the user at the time of consent, among other things. You can read about the <a href="https://www.iubenda.com/en/help/5428-gdpr-guide#records-of-consent" target="_blank">full requirements here</a>.', 'iubenda' ) . '
589
- </p>';
590
- }
591
- ?>
592
- </div>
593
-
594
- <?php
595
- if ( $tab_key === 'cs' ) {
596
- // add per-purpose notice
597
- if ( iubenda()->options['cs']['skip_parsing'] ) {
598
- $iubenda_code = '';
599
-
600
- if ( iubenda()->multilang === true && defined( 'ICL_LANGUAGE_CODE' ) && isset( iubenda()->options['cs']['code_' . ICL_LANGUAGE_CODE] ) ) {
601
- $iubenda_code = iubenda()->options['cs']['code_' . ICL_LANGUAGE_CODE];
602
-
603
- // no code for current language, use default
604
- if ( ! $iubenda_code )
605
- $iubenda_code = iubenda()->options['cs']['code_default'];
606
- } else
607
- $iubenda_code = iubenda()->options['cs']['code_default'];
608
-
609
- $per_purpose_enabled = preg_match( '/(?:"|\')perPurposeConsent(?:"|\')\: *(?:"|\'*)true(?:"|\'*)/', $iubenda_code );
610
- $reject_enabled = preg_match( '/(?:"|\')rejectButtonDisplay(?:"|\')\: *(?:"|\'*)true(?:"|\'*)/', $iubenda_code );
611
-
612
- if ( $per_purpose_enabled || $reject_enabled )
613
- $this->add_notice( 'iub_per_purpose_enabled', sprintf( __( 'If you are using per-purpose script blocking or Reject option please disable the "Leave scripts untouched on the page if the user has already given consent" option. <a href="%s" target="_self">Disable now</a>', 'iubenda' ), esc_url( add_query_arg( 'action', 'disable_skip_parsing', $redirect_to ) ) ), 'notice' );
614
- }
615
-
616
- // add AMP notice
617
- if ( iubenda()->options['cs']['amp_support'] && iubenda()->options['cs']['amp_template_done'] ) {
618
- $ssl_support = true;
619
-
620
- // multilang support
621
- if ( iubenda()->multilang && ! empty( iubenda()->languages ) ) {
622
- foreach ( iubenda()->languages as $lang_id => $lang_name ) {
623
- $url = iubenda()->options['cs']['amp_source'] === 'remote' ? iubenda()->options['cs']['amp_template'][$lang_id] : iubenda()->AMP->get_amp_template_url( $lang_id );
624
- $bits = explode( '/', $url );
625
-
626
- if ( $bits[0] === 'http:' )
627
- $ssl_support = false;
628
- }
629
- } else {
630
- $url = iubenda()->options['cs']['amp_source'] === 'remote' ? iubenda()->options['cs']['amp_template'] : iubenda()->AMP->get_amp_template_url();
631
- $bits = explode( '/', $url );
632
-
633
- if ( $bits[0] === 'http:' )
634
- $ssl_support = false;
635
- }
636
-
637
- if ( ! $ssl_support )
638
- $this->add_notice( 'iub_amp_ssl_required', __( 'AMP configuration file requires HTTPS. Make sure your SSL Certificate is configured correctly.', 'iubenda' ), 'error' );
639
- }
640
-
641
- }
642
-
643
- // render custom notices
644
- $this->print_notices();
645
- ?>
646
-
647
- <h2 style="display: none;"></h2>
648
- <h2 class="nav-tab-wrapper iubenda-tab-wrapper">
649
- <a class="nav-tab<?php echo $tab_key == 'cs' ? ' nav-tab-active' : ''; ?>" href="<?php echo esc_url( iubenda()->base_url ); ?>"><?php _e( 'Cookie Solution', 'iubenda' ); ?></a>
650
- <a class="nav-tab<?php echo $tab_key == 'cons' ? ' nav-tab-active' : ''; ?>" href="<?php echo esc_url( add_query_arg( array( 'tab' => 'cons' ), iubenda()->base_url ) ); ?>"><?php _e( 'Consent Solution', 'iubenda' ); ?></a>
651
- </h2>
652
-
653
- <div id="iubenda-settings">
654
-
655
- <form id="iubenda-tabs" action="options.php" method="post">
656
-
657
-
658
- <?php
659
- if ( $tab_key === 'cs' ) {
660
- echo '<p>' . sprintf( __( 'This plugin drastically reduces the need for direct interventions in the code of the site by integrating with iubenda\'s Cookie Solution. It provides a fully customizable cookie banner, dynamically generates a cookie policy <a href="%s" target="_blank">to match the services in use on your site</a>, and, fully manages cookie-related consent - including the blocking of the most common widgets and third-party cookies before consent is received - in order to comply with the GDPR and ePrivacy.', 'iubenda' ), 'https://www.iubenda.com/en/help/19004-how-to-use-the-site-scanner-from-within-the-generator' ) . '</p>';
661
- } else {
662
- echo '<p>' . __( 'Maintaining valid records of consent is a vital part of privacy compliance in general, and it is specifically required under the GDPR. These records should include a userid, timestamp, consent proof, record of the consenting action, and the legal documents available to the user at the time of consent, among other things. This plugin is THE most complete solution for recording, sorting and maintaining GDPR records of consent*. The plugin also boasts built-in compatibility with WordPress comment form, Contact Form 7 and WP Forms plugins for your convenience, but can be manually integrated with any type of web-form and can even store consent proofs for consents collected offline (e.g in-store sign-ups) via WP media upload.' ) . '</p>';
663
- }
664
- ?>
665
-
666
- <?php
667
- settings_fields( $this->tabs[$tab_key]['key'] );
668
- do_settings_sections( $this->tabs[$tab_key]['key'] );
669
-
670
- if ( ! in_array( $this->action, array( 'save', 'edit' ) ) ) {
671
- echo ' <p class="submit submit-' . $tab_key . '">';
672
-
673
- // consent solution tab only
674
- if ( $tab_key != 'cs' && ! empty( iubenda()->options['cons']['public_api_key'] ) ) {
675
- echo '<a href="' . esc_url( add_query_arg( array( 'tab' => 'cons', 'action' => 'autodetect' ), iubenda()->base_url ) ) . '" class="button button-primary button-large iub-autodetect-forms">' . esc_html__( 'Autodetect Forms', 'iubenda' ) . '</a>';
676
- echo '<br />';
677
- }
678
- submit_button( '', 'primary', $this->tabs[$tab_key]['submit'], false );
679
- echo ' ';
680
- submit_button( __( 'Reset to defaults', 'iubenda' ), 'secondary', $this->tabs[$tab_key]['reset'], false );
681
- echo ' </p>';
682
- }
683
- ?>
684
-
685
- </form>
686
-
687
- </div>
688
-
689
- <div id="iubenda-footer">
690
- <?php echo '
691
- <p class="iubenda-text">
692
- <span class="iubenda-title">' . __( 'Need support for this plugin?', 'iubenda' ) . '</span><br />
693
- ' . sprintf( __( "Visit our <a href=\"%s\" class=\"iubenda-url\" target=\"_blank\">support forum.</a>", 'iubenda' ), $this->links['support_forum'] ) . '
694
- </p>';
695
- ?>
696
- </div>
697
-
698
- <div class="clear"></div>
699
- </div>
700
- <?php
701
- }
702
-
703
- /**
704
- * Code option.
705
- *
706
- * @return mixed
707
- */
708
- public function iub_code() {
709
- // multilang support
710
- if ( iubenda()->multilang && ! empty( iubenda()->languages ) ) {
711
- echo '
712
- <div id="contextual-help-wrap" class="contextual-help-wrap hidden" tabindex="-1" style="display: block;">
713
- <div id="contextual-help-back" class="contextual-help-back"></div>
714
- <div id="contextual-help-columns" class="contextual-help-columns">
715
- <div class="contextual-help-tabs">
716
- <ul>';
717
- foreach ( iubenda()->languages as $lang_id => $lang_name ) {
718
- echo '
719
- <li class="' . ( iubenda()->lang_default == $lang_id ? 'active' : '' ) . '">
720
- <a href="#tab-panel-' . $lang_id . '" aria-controls="tab-panel-' . $lang_id . '">' . $lang_name . '</a>
721
- </li>';
722
- }
723
- echo '
724
- </ul>
725
- </div>
726
-
727
- <div id="contextual-help-tabs-wrap" class="contextual-help-tabs-wrap">';
728
- foreach ( iubenda()->languages as $lang_id => $lang_name ) {
729
- // get code for the language
730
- $code = ! empty( iubenda()->options['cs']['code_' . $lang_id] ) ? html_entity_decode( iubenda()->parse_code( iubenda()->options['cs']['code_' . $lang_id] ) ) : '';
731
- // handle default, if empty
732
- $code = empty( $code ) && $lang_id == iubenda()->lang_default ? html_entity_decode( iubenda()->parse_code( iubenda()->options['cs']['code_default'] ) ) : $code;
733
-
734
- echo '
735
- <div id="tab-panel-' . $lang_id . '" class="help-tab-content' . ( iubenda()->lang_default == $lang_id ? ' active' : '' ) . '">
736
- <textarea name="iubenda_cookie_law_solution[code_' . $lang_id . ']" class="large-text" cols="50" rows="10">' . $code . '</textarea>
737
- <p class="description">' . sprintf( __( 'Enter the iubenda code for %s.', 'iubenda' ), $lang_name ) . '</p>
738
- </div>';
739
- }
740
- echo '
741
- </div>
742
- </div>
743
- </div>';
744
- } else {
745
- echo '
746
- <div id="iub_code_default">
747
- <textarea name="iubenda_cookie_law_solution[code_default]" class="large-text" cols="50" rows="10">' . html_entity_decode( iubenda()->parse_code( iubenda()->options['cs']['code_default'] ) ) . '</textarea>
748
- <p class="description">' . __( 'Enter the iubenda code.', 'iubenda' ) . '</p>
749
- </div>';
750
- }
751
- }
752
-
753
- /**
754
- * Custom scripts option.
755
- *
756
- * @return void
757
- */
758
- public function iub_custom_scripts() {
759
- echo '
760
- <div id="contextual-help-wrap-2" class="contextual-help-wrap hidden" tabindex="-1" style="display: block;">
761
- <div id="contextual-help-back-2" class="contextual-help-back"></div>
762
- <div id="contextual-help-columns-2" class="contextual-help-columns">
763
- <div class="contextual-help-tabs">
764
- <ul>
765
- <li class="active">
766
- <a href="#tab-panel-scripts" aria-controls="tab-panel-scripts">' . esc_html__( 'Scripts', 'iubenda' ) . '</a>
767
- </li>
768
- <li>
769
- <a href="#tab-panel-iframes" aria-controls="tab-panel-iframes">' . esc_html__( 'Iframes', 'iubenda' ) . '</a>
770
- </li>
771
- </ul>
772
- </div>
773
- <div id="contextual-help-tabs-wrap-2" class="contextual-help-tabs-wrap">
774
- <div id="tab-panel-scripts" class="help-tab-content active">
775
- <p class="description">' . __( 'Provide a list of custom scripts you\'d like to block and assign their purpose.', 'iubenda' ) . '</p>
776
- <div id="custom-script-field-template" class="template-field" style="display: none;">
777
- <input type="text" class="regular-text" value="" name="iubenda_cookie_law_solution[custom_scripts][script][]" placeholder="' . __( 'Enter custom script', 'iubenda' ) . '" /> ' . $this->render_tag_types( 'script', 0 ) . ' <a href="#" class="remove-custom-script-field button-secondary" title="' . __( 'Remove', 'iubenda' ) . '">-</a>
778
- </div>';
779
-
780
- if ( ! empty( iubenda()->options['cs']['custom_scripts'] ) ) {
781
- foreach ( iubenda()->options['cs']['custom_scripts'] as $script => $type ) {
782
- echo '
783
- <div class="custom-script-field">
784
- <input type="text" class="regular-text" value="' . esc_attr( $script ) . '" name="iubenda_cookie_law_solution[custom_scripts][script][]" placeholder="' . __( 'Enter custom script', 'iubenda' ) . '" /> ' . $this->render_tag_types( 'script', $type ) . ' <a href="#" class="remove-custom-script-field button-secondary" title="' . __( 'Remove', 'iubenda' ) . '">-</a>
785
- </div>';
786
- }
787
- }
788
-
789
- echo '
790
- <a href="#" class="add-custom-script-field button-secondary">Add New Script</a>
791
- </div>
792
- <div id="tab-panel-iframes" class="help-tab-content">
793
- <p class="description">' . __( 'Provide a list of custom iframes you\'d like to block and assign their purpose. ', 'iubenda' ) . '</p>
794
- <div id="custom-iframe-field-template" class="template-field" style="display: none;">
795
- <input type="text" class="regular-text" value="" name="iubenda_cookie_law_solution[custom_iframes][iframe][]" placeholder="' . __( 'Enter custom iframe', 'iubenda' ) . '" /> ' . $this->render_tag_types( 'iframe', 0 ) . ' <a href="#" class="remove-custom-iframe-field button-secondary" title="' . __( 'Remove', 'iubenda' ) . '">-</a>
796
- </div>';
797
-
798
- if ( ! empty( iubenda()->options['cs']['custom_iframes'] ) ) {
799
- foreach ( iubenda()->options['cs']['custom_iframes'] as $iframe => $type ) {
800
- echo '
801
- <div class="custom-iframe-field">
802
- <input type="text" class="regular-text" value="' . esc_attr( $iframe ) . '" name="iubenda_cookie_law_solution[custom_iframes][iframe][]" placeholder="' . __( 'Enter custom iframe', 'iubenda' ) . '" /> ' . $this->render_tag_types( 'iframe', $type ) . ' <a href="#" class="remove-custom-iframe-field button-secondary" title="' . __( 'Remove', 'iubenda' ) . '">-</a>
803
- </div>';
804
- }
805
- }
806
-
807
- echo '
808
- <a href="#" class="add-custom-iframe-field button-secondary">Add New Iframe</a>
809
- </div>
810
- </div>
811
- </div>
812
- </div>';
813
- }
814
-
815
- /**
816
- * Prepare tag types select.
817
- *
818
- * @param string $type
819
- * @param int $selected
820
- * @return string
821
- */
822
- function render_tag_types( $type, $selected ) {
823
- $html = '<select name="iubenda_cookie_law_solution[custom_' . $type . 's][type][]">';
824
-
825
- foreach ( $this->tag_types as $tag_id => $tag_name ) {
826
- $html .= '<option value="' . esc_attr( $tag_id ) . '" ' . selected( $selected, $tag_id, false ) . '>' . esc_html( $tag_name ) . '</option>';
827
- }
828
-
829
- return $html . '</select>';
830
- }
831
-
832
- /**
833
- * Parsing option.
834
- *
835
- * @return mixed
836
- */
837
- public function iub_parse() {
838
- echo '
839
- <div id="iub_parse_container">
840
- <label><input id="iub_parse" type="checkbox" name="iubenda_cookie_law_solution[parse]" value="1" ' . checked( true, (bool) iubenda()->options['cs']['parse'], false ) . '/>' . __( 'Automatically block scripts detected by the plugin', 'iubenda' ) . '</label>
841
- <p class="description">' . '(' . sprintf( __( "see <a href=\"%s\" target=\"_blank\">our documentation</a> for the list of detected scripts.", 'iubenda' ), $this->links['documentation'] ) . ')' . '</p>
842
- <div id="iub_parser_engine_container"' . ( iubenda()->options['cs']['parse'] === false ? ' style="display: none;"' : '' ) . '>
843
- <div>
844
- <label><input id="iub_parser_engine-new" type="radio" name="iubenda_cookie_law_solution[parser_engine]" value="new" ' . checked( 'new', iubenda()->options['cs']['parser_engine'], false ) . ' />' . __( 'Primary', 'iubenda' ) . '</label>
845
- <label><input id="iub_parser_engine-default" type="radio" name="iubenda_cookie_law_solution[parser_engine]" value="default" ' . checked( 'default', iubenda()->options['cs']['parser_engine'], false ) . ' />' . __( 'Secondary', 'iubenda' ) . '</label>
846
- <p class="description">' . __( 'Select parsing engine.', 'iubenda' ) . '</p>
847
- </div>
848
- <div>
849
- <label><input id="iub_skip_parsing" type="checkbox" name="iubenda_cookie_law_solution[skip_parsing]" value="1" ' . checked( true, (bool) iubenda()->options['cs']['skip_parsing'], false ) . '/>' . __( 'Leave scripts untouched on the page if the user has already given consent', 'iubenda' ) . '</label>
850
- <p class="description">(' . __( "improves performance, highly recommended, to be deactivated only if your site uses a caching system or if you're collecting per-category consent.", 'iubenda' ) . ')</p>
851
- </div>
852
- </div>
853
- </div>';
854
- }
855
-
856
- /**
857
- * Ctype option.
858
- *
859
- * @return mixed
860
- */
861
- public function iub_ctype() {
862
- echo '
863
- <div id="iub_ctype_container">
864
- <label><input id="iub_ctype" type="checkbox" name="iubenda_cookie_law_solution[ctype]" value="1" ' . checked( true, (bool) iubenda()->options['cs']['ctype'], false ) . '/>' . __( 'Restrict the plugin to run only for requests that have "Content-type: text / html" (recommended)', 'iubenda' ) . '</label>
865
- </div>';
866
- }
867
-
868
- /**
869
- * RSS feed option.
870
- *
871
- * @return mixed
872
- */
873
- public function iub_output_feed() {
874
- echo '
875
- <div id="iub_output_feed_container">
876
- <label><input id="iub_output_feed" type="checkbox" name="iubenda_cookie_law_solution[output_feed]" value="1" ' . checked( true, (bool) iubenda()->options['cs']['output_feed'], false ) . '/>' . __( 'Do not run the plugin inside the RSS feed (recommended)', 'iubenda' ) . '</label>
877
- </div>';
878
- }
879
-
880
- /**
881
- * POST request option.
882
- *
883
- * @return mixed
884
- */
885
- public function iub_output_post() {
886
- echo '
887
- <div id="iub_output_post_container">
888
- <label><input id="iub_output_post" type="checkbox" name="iubenda_cookie_law_solution[output_post]" value="1" ' . checked( true, (bool) iubenda()->options['cs']['output_post'], false ) . '/>' . __( 'Do not run the plugin on POST requests (recommended)', 'iubenda' ) . '</label>
889
- </div>';
890
- }
891
-
892
- /**
893
- * Menu option.
894
- *
895
- * @return mixed
896
- */
897
- public function iub_menu_position() {
898
- echo '
899
- <div id="iub_menu_position_container">
900
- <label><input id="iub_menu_position-topmenu" type="radio" name="iubenda_cookie_law_solution[menu_position]" value="topmenu" ' . checked( 'topmenu', iubenda()->options['cs']['menu_position'], false ) . ' />' . __( 'Top menu', 'iubenda' ) . '</label>
901
- <label><input id="iub_menu_position-submenu" type="radio" name="iubenda_cookie_law_solution[menu_position]" value="submenu" ' . checked( 'submenu', iubenda()->options['cs']['menu_position'], false ) . ' />' . __( 'Submenu', 'iubenda' ) . '</label>
902
- <p class="description">' . __( 'Select whether to display iubenda in a top admin menu or the Settings submenu.', 'iubenda' ) . '</p>
903
- </div>';
904
- }
905
-
906
- /**
907
- * Google AMP support option.
908
- *
909
- * @return mixed
910
- */
911
- public function iub_amp_support() {
912
- echo '
913
- <div id="iub_amp_support_container">
914
- <label><input id="iub_amp_support" type="checkbox" name="iubenda_cookie_law_solution[amp_support]" value="1" ' . checked( true, (bool) iubenda()->options['cs']['amp_support'], false ) . '/>' . __( 'Enable Google AMP support.', 'iubenda' ) . '</label>
915
- <p class="description">' . sprintf( __( 'This feature enables iubenda on AMP pages via the <a href="%s" target="_blank">AMP</a> and <a href="%s" target="_blank">AMP for WP</a> plugins. AMP requires specific configuration parameters and a page hosted on your domain where the configuration is loaded from. <a href="%s" target="_blank">Learn more on iubenda and AMP</a>.', 'iubenda' ), 'https://wordpress.org/plugins/amp/', 'https://wordpress.org/plugins/accelerated-mobile-pages/', 'https://www.iubenda.com/en/help/22135-cookie-solution-amp#wordpress' ) . '</p>
916
- <div id="iub_amp_options_container"' . ( iubenda()->options['cs']['amp_support'] === false ? ' style="display: none;"' : '' ) . '>
917
- <div>
918
- <label><input id="iub_amp_source-local" class="iub_amp_source" type="radio" name="iubenda_cookie_law_solution[amp_source]" value="local" ' . checked( 'local', iubenda()->options['cs']['amp_source'], false ) . ' />' . __( 'Auto-generated configuration file', 'iubenda' ) . '</label>
919
- <label><input id="iub_amp_source-remote" class="iub_amp_source" type="radio" name="iubenda_cookie_law_solution[amp_source]" value="remote" ' . checked( 'remote', iubenda()->options['cs']['amp_source'], false ) . ' />' . __( 'Custom configuration file', 'iubenda' ) . '</label>
920
- <p class="description">' . __( 'Select the iubenda AMP configuration file location.', 'iubenda' ) . '</p>
921
- </div>
922
- <div id="iub_amp_template-local"' . ( iubenda()->options['cs']['amp_source'] === 'remote' ? ' style="display: none;"' : '' ) . '>';
923
- if ( empty( iubenda()->options['cs']['amp_template_done'] ) ) {
924
- echo '
925
- <p class="description">' . __( 'No file available. Save changes to generate iubenda AMP configuration file.', 'iubenda' ) . '</p>';
926
- } else {
927
- // multilang support
928
- if ( iubenda()->multilang && ! empty( iubenda()->languages ) ) {
929
- foreach ( iubenda()->languages as $lang_id => $lang_name ) {
930
- echo $lang_name . ':
931
- <a href="' . iubenda()->AMP->get_amp_template_url( $lang_id ) . '" target="_blank">' . iubenda()->AMP->get_amp_template_url( $lang_id ) . '</a><br />';
932
- }
933
- } else {
934
- echo '
935
- <a href="' . iubenda()->AMP->get_amp_template_url() . '" target="_blank">' . iubenda()->AMP->get_amp_template_url() . '</a>';
936
- }
937
- }
938
- echo '
939
- </div>
940
- <div id="iub_amp_template-remote"' . ( iubenda()->options['cs']['amp_source'] === 'local' ? ' style="display: none;"' : '' ) . '>';
941
-
942
- // multilang support
943
- if ( iubenda()->multilang && ! empty( iubenda()->languages ) ) {
944
- foreach ( iubenda()->languages as $lang_id => $lang_name ) {
945
- echo $lang_name . ':
946
- <label><input id="iub_amp_template-' . $lang_id . '" type="text" class="regular-text" name="iubenda_cookie_law_solution[amp_template][' . $lang_id . ']" value="' . ( isset( iubenda()->options['cs']['amp_template'][$lang_id] ) ? esc_url( iubenda()->options['cs']['amp_template'][$lang_id] ) : '' ) . '" /></label><br />';
947
- }
948
- } else {
949
- echo '
950
- <label><input id="iub_amp_template" type="text" class="regular-text" name="iubenda_cookie_law_solution[amp_template]" value="' . ( isset( iubenda()->options['cs']['amp_template'] ) ? esc_url( iubenda()->options['cs']['amp_template'] ) : '' ) . '" /></label>';
951
- }
952
- echo '
953
- <p class="description">' . __( 'If you\'re experiencing issues with AMP setup download the generated iubenda AMP configuration file, upload it to any SSL server and paste the file link to the field above.', 'iubenda' ) . '</p>
954
- </div>
955
- <p class="description">' . sprintf( __( 'Seeing the AMP cookie notice when testing from Google but not when visiting your AMP pages directly? <a href="%s" target="_blank">Learn how to fix it</a>.', 'iubenda' ), 'https://www.iubenda.com/en/help/3182-cookie-solution-amp#amp-domain' ) . '</p>
956
- </div>
957
- </div>';
958
- }
959
-
960
- /**
961
- * Deactivation option.
962
- *
963
- * @return mixed
964
- */
965
- public function iub_deactivation() {
966
- echo '
967
- <div id="iub_deactivation_container">
968
- <label><input id="iub_deactivation" type="checkbox" name="iubenda_cookie_law_solution[deactivation]" value="1" ' . checked( true, (bool) iubenda()->options['cs']['deactivation'], false ) . '/>' . __( 'Delete all plugin data upon deactivation', 'iubenda' ) . '</label>
969
- </div>';
970
- }
971
-
972
- /**
973
- * Public API Key option.
974
- *
975
- * @return mixed
976
- */
977
- public function iub_public_api_key() {
978
- echo '
979
- <div id="iub_public_api_key_container">
980
- <label><input id="iub_public_api_key" type="text" class="regular-text" name="iubenda_consent_solution[public_api_key]" value="' . iubenda()->options['cons']['public_api_key'] . '" /></label>
981
- <p class="description">' . __( 'Enter your iubenda Javascript library public API key.', 'iubenda' ) . '</p>
982
- </div>';
983
- }
984
-
985
- /**
986
- * Forms list.
987
- *
988
- * @return mixed
989
- */
990
- public function iubenda_consent_forms() {
991
- $form_id = ! empty( $_GET['form_id'] ) ? absint( $_GET['form_id'] ) : 0;
992
- $form = ! empty( $form_id ) ? iubenda()->forms->get_form( $form_id ) : false;
993
-
994
- $supported_forms = iubenda()->forms->sources;
995
-
996
- echo '
997
- <p class="description">' . __( 'This section lists the forms available for field mapping. The plugin currently supports & detects: WordPress Comment, Contact Form 7, WooCommerce Checkout and WP Forms.', 'iubenda' ) . '</p>';
998
-
999
- // list screen
1000
- if ( ! class_exists( 'WP_List_Table' ) )
1001
- include_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
1002
-
1003
- include_once( IUBENDA_PLUGIN_PATH . '/includes/forms-list-table.php' );
1004
-
1005
- $list_table = new iubenda_List_Table_Forms();
1006
-
1007
- echo '
1008
- <div id="iubenda-consent-forms">';
1009
- $list_table->views();
1010
- $list_table->prepare_items();
1011
- $list_table->display();
1012
-
1013
- echo '
1014
- </div>';
1015
- }
1016
-
1017
- /**
1018
- * Single form.
1019
- *
1020
- * @return mixed
1021
- */
1022
- public function iubenda_consent_form() {
1023
- $form_id = ! empty( $_GET['form_id'] ) ? absint( $_GET['form_id'] ) : 0;
1024
- $form = ! empty( $form_id ) ? iubenda()->forms->get_form( $form_id ) : false;
1025
-
1026
- if ( ! $form )
1027
- return;
1028
-
1029
- $status = isset( $form->post_status ) && in_array( $form->post_status, array_keys( iubenda()->forms->statuses ) ) ? esc_attr( $form->post_status ) : 'publish';
1030
- $subject = isset( $form->form_subject ) && is_array( $form->form_subject ) ? array_map( 'esc_attr', $form->form_subject ) : array();
1031
- $preferences = isset( $form->form_preferences ) && is_array( $form->form_preferences ) ? array_map( 'esc_attr', $form->form_preferences ) : array();
1032
- $exclude = isset( $form->form_exclude ) && is_array( $form->form_exclude ) ? array_map( 'esc_attr', $form->form_exclude ) : array();
1033
- $legal_notices = isset( $form->form_legal_notices ) && is_array( $form->form_legal_notices ) ? array_map( 'esc_attr', $form->form_legal_notices ) : array();
1034
-
1035
- $available_fields = array();
1036
-
1037
- if ( ! empty( $form->form_fields ) && is_array( $form->form_fields ) ) {
1038
- foreach ( $form->form_fields as $index => $form_field ) {
1039
- if ( is_array( $form_field ) ) {
1040
- // print_r( $form_field );
1041
- $available_fields[] = $form_field['label'] . ' (' . $form_field['type'] . ')';
1042
- } else {
1043
- $available_fields[] = $form_field;
1044
- }
1045
- }
1046
- }
1047
-
1048
- // print_r( $form );
1049
-
1050
- echo '
1051
- <div id="poststuff">
1052
- <div id="post-body" class="metabox-holder columns-2">
1053
- <div id="post-body-content">
1054
- <div id="titlediv">
1055
- <div id="titlewrap">
1056
- <h1>' . $form->post_title . '</h1>
1057
- </div>
1058
- <p class="description">' . sprintf( __( '%s form title.', 'iubenda' ), ( array_key_exists( $form->form_source, iubenda()->forms->sources ) ? iubenda()->forms->sources[$form->form_source] : __( 'Unknown', 'iubenda' ) ) ) . '</p>
1059
-
1060
- <div style="margin-top: 18px"><strong>' . __( 'Available form fields:', 'iubenda' ) . '</strong><br /><p class="description">' . implode( ', ', $available_fields ) . '</p></div>
1061
- </div>
1062
- </div>
1063
- <div id="postbox-container-1" class="postbox-container">
1064
- <div id="side-sortables" class="">
1065
- <div id="submitdiv" class="postbox ">
1066
- <h3 class="hndle"><span>' . __( 'Publish' ) . '</span></h3>
1067
- <div class="inside">
1068
- <div id="submitpost" class="submitbox">
1069
- <div id="minor-publishing">
1070
- <div class="misc-pub-section misc-pub-post-status">
1071
- <label for="status">' . __( 'Status' ) . ':</label>
1072
- <div id="status-select" class="" style="margin: 3px 0 0;">
1073
- <select id="status" name="status">';
1074
- foreach ( iubenda()->forms->statuses as $name => $label ) {
1075
- echo '
1076
- <option value="' . $name . '"' . selected( $form->post_status, $name, true ) . '>' . $label . '</option>';
1077
- }
1078
- echo '
1079
- </select>
1080
- </div>
1081
- </div>
1082
- <div id="major-publishing-actions">
1083
- <div id="delete-action">
1084
- <a class="submitdelete deletion" href="' . esc_url( add_query_arg( array( 'tab' => 'cons' ), iubenda()->base_url ) ) . '">' . __( 'Cancel' ) . '</a>
1085
- </div>
1086
- <div id="publishing-action">
1087
- <span class="spinner"></span>
1088
- <input type="hidden" value="' . $form->ID . '" name="form_id">
1089
- <input id="publish" class="button button-primary button-large" type="submit" value="' . __( 'Save' ) . '" name="save">
1090
- </div>
1091
- <div class="clear"></div>
1092
- </div>
1093
- </div>
1094
- </div>
1095
- </div>
1096
- </div>
1097
- </div>
1098
- </div>
1099
- <div id="postbox-container-2" class="postbox-container">
1100
- <div id="normal-sortables" class="meta-box-sortables">
1101
- <div id="map-fields" class="postbox">
1102
- <h3 class="hndle ui-sortable-handle"><span>' . __( 'Map fields', 'iubenda' ) . '</span></h3>
1103
- <div class="inside">
1104
- <table class="widefat">
1105
- <tbody>
1106
- <tr>
1107
- <td class="label table-label">
1108
- <h4>' . __( 'Subject fields', 'iubenda' ) . ' <span class="required">(required)</span></h4>
1109
- <p class="description">' . __( 'Subject fields allow you to store a series of identifying values about your individual subjects/users. Please map the subject field with the corresponding form fields where applicable.', 'iubenda' ) . '</p>
1110
- </td>
1111
- <td>
1112
- <table class="widefat subject-table">
1113
- <thead>
1114
- <td class="label">' . __( 'Subject field', 'iubenda' ) . '</td>
1115
- <td class="label">' . __( 'Form field', 'iubenda' ) . '</td>
1116
- </thead>
1117
- <tbody>';
1118
-
1119
- foreach ( $this->subject_fields as $field_name => $field_label ) {
1120
- $selected = isset( $subject[$field_name] ) ? $subject[$field_name] : '';
1121
- $none = $field_name == 'id' ? __( 'Autogenerated', 'iubenda' ) : __( 'None', 'iubenda' );
1122
-
1123
- echo '
1124
- <tr class="subject-field options-field">
1125
- <td>' . $field_name . ' (' . $field_label . ')' . '</td>
1126
- <td>
1127
- <select class="subject-fields-select select-' . $field_name . '" name="subject[' . $field_name . ']">
1128
- <option value="" ' . selected( $selected, '', false ) . '>' . $none . '</option>';
1129
- if ( ! empty( $form->form_fields ) ) {
1130
- foreach ( $form->form_fields as $index => $form_field ) {
1131
- // get field data
1132
- $form_field_value = is_array( $form_field ) ? $index : $form_field;
1133
- $form_field_label = is_array( $form_field ) ? $form_field['label'] . ' (' . $form_field['type'] . ')' : $form_field;
1134
- $form_field_selected = is_array( $form_field ) ? $index : $form_field;
1135
-
1136
- echo '<option value="' . $form_field_value . '" ' . selected( $selected, $form_field_selected, false ) . '>' . $form_field_label . '</option>';
1137
- }
1138
- }
1139
- echo '
1140
- </select>
1141
- </td>
1142
- </tr>
1143
- ';
1144
- }
1145
- echo '
1146
- </tbody>
1147
- </table>
1148
- </td>
1149
- </tr>
1150
- <tr>
1151
- <td class="label table-label">
1152
- <h4>' . __( 'Preferences fields', 'iubenda' ) . ' <span class="required">(required)</span></h4>
1153
- <p class="description">' . __( 'Preferences fields allow you to store a record of the various opt-ins points at which the user has agreed or given consent, such as fields for agreeing to terms and conditions, newsletter, profiling, etc. *Please create at least one preference field.', 'iubenda' ) . '</p>
1154
- </td>
1155
- <td>
1156
- <table class="widefat preferences-table">
1157
- <thead>
1158
- <td class="label">' . __( 'Preferences field', 'iubenda' ) . '</td>
1159
- <td class="label">' . __( 'Form field', 'iubenda' ) . '</td>
1160
- </thead>
1161
- <tbody>';
1162
- echo '
1163
- <tr id="preferences-field-template" class="template-field" style="display: none;">
1164
- <td><input type="text" class="regular-text" value="" name="preferences[__PREFERENCE_ID__][field]" placeholder="' . __( 'Enter field name', 'iubenda' ) . '" /></td>
1165
- <td>
1166
- <select class="preferences-fields-select select-' . $field_name . '" name="preferences[__PREFERENCE_ID__][value]">';
1167
- if ( ! empty( $form->form_fields ) ) {
1168
- foreach ( $form->form_fields as $index => $form_field ) {
1169
- // get field data
1170
- $form_field_value = is_array( $form_field ) ? $index : $form_field;
1171
- $form_field_label = is_array( $form_field ) ? $form_field['label'] . ' (' . $form_field['type'] . ')' : $form_field;
1172
-
1173
- echo '<option value="' . $form_field_value . '">' . $form_field_label . '</option>';
1174
- }
1175
- }
1176
- echo '
1177
- </select>
1178
- <a href="javascript:void(0)" class="remove-preferences-field button-secondary" title="' . __( 'Remove', 'iubenda' ) . '">-</a>
1179
- </td>
1180
- </tr>';
1181
-
1182
- if ( $preferences ) {
1183
- $index = 0;
1184
-
1185
- foreach ( $preferences as $field_name => $field_value ) {
1186
- $selected = isset( $preferences[$field_name] ) ? $preferences[$field_name] : '';
1187
-
1188
- echo '
1189
- <tr class="preferences-field options-field">
1190
- <td><input type="text" class="regular-text" value="' . $field_name . '" name="preferences[' . $index . '][field]" placeholder="' . __( 'Enter field name', 'iubenda' ) . '" /></td>
1191
- <td>
1192
- <select class="preferences-fields-select select-' . $field_name . '" name="preferences[' . $index . '][value]">';
1193
- if ( ! empty( $form->form_fields ) ) {
1194
- foreach ( $form->form_fields as $index => $form_field ) {
1195
- // get field data
1196
- $form_field_value = is_array( $form_field ) ? $index : $form_field;
1197
- $form_field_label = is_array( $form_field ) ? $form_field['label'] . ' (' . $form_field['type'] . ')' : $form_field;
1198
- $form_field_selected = is_array( $form_field ) ? $index : $form_field;
1199
-
1200
- echo '<option value="' . $form_field_value . '" ' . selected( $selected, $form_field_selected, false ) . '>' . $form_field_label . '</option>';
1201
- }
1202
- }
1203
- echo '
1204
- </select>
1205
- <a href="javascript:void(0)" class="remove-preferences-field button-secondary" title="' . __( 'Remove', 'iubenda' ) . '">-</a>
1206
- </td>
1207
- </tr>';
1208
-
1209
- $index++;
1210
- }
1211
- }
1212
-
1213
- echo '
1214
- <tr class="submit-field"><td colspan="2"><a href="javascript:void(0)" class="add-preferences-field button-secondary">' . __( 'Add New Preference', 'iubenda' ) . '</a></td></tr>
1215
- </tbody>
1216
- </table>
1217
- </td>
1218
- </tr>
1219
- <tr>
1220
- <td class="label table-label">
1221
- <h4>' . __( 'Exclude fields', 'iubenda' ) . '</h4>
1222
- <p class="description">' . __( 'Exclude fields allow you to create a list of fields that you would like to exclude from your Consent Solution recorded proofs (for e.g. password or other fields not related to the consent).', 'iubenda' ) . '</p>
1223
- </td>
1224
- <td>
1225
- <table class="widefat exclude-table">
1226
- <thead>
1227
- <td class="label">' . __( 'Exclude field', 'iubenda' ) . '</td>
1228
- <td class="label"></td>
1229
- </thead>
1230
- <tbody>';
1231
- echo '
1232
- <tr id="exclude-field-template" class="template-field" style="display: none;">
1233
- <td>
1234
- <select class="exclude-fields-select select-' . $field_name . '" name="exclude[__EXCLUDE_ID__][field]">';
1235
- if ( ! empty( $form->form_fields ) ) {
1236
- foreach ( $form->form_fields as $index => $form_field ) {
1237
- // get field data
1238
- $form_field_value = is_array( $form_field ) ? $index : $form_field;
1239
- $form_field_label = is_array( $form_field ) ? $form_field['label'] . ' (' . $form_field['type'] . ')' : $form_field;
1240
-
1241
- echo '<option value="' . $form_field_value . '">' . $form_field_label . '</option>';
1242
- }
1243
- }
1244
- echo '
1245
- </select>
1246
- <a href="javascript:void(0)" class="remove-exclude-field button-secondary" title="' . __( 'Remove', 'iubenda' ) . '">-</a>
1247
- </td>
1248
- <td></td>
1249
-
1250
- </tr>';
1251
-
1252
- if ( $exclude ) {
1253
- $index = 0;
1254
-
1255
- foreach ( $exclude as $index => $field_name ) {
1256
- $selected = isset( $exclude[$index] ) ? $exclude[$index] : '';
1257
-
1258
- echo '
1259
- <tr class="exclude-field options-field">
1260
- <td>
1261
- <select class="exclude-fields-select select-' . $field_name . '" name="exclude[' . $index . '][field]">';
1262
- if ( ! empty( $form->form_fields ) ) {
1263
- foreach ( $form->form_fields as $index => $form_field ) {
1264
- // get field data
1265
- $form_field_value = is_array( $form_field ) ? $index : $form_field;
1266
- $form_field_label = is_array( $form_field ) ? $form_field['label'] . ' (' . $form_field['type'] . ')' : $form_field;
1267
- $form_field_selected = is_array( $form_field ) ? $index : $form_field;
1268
-
1269
- echo '<option value="' . $form_field_value . '" ' . selected( $selected, $form_field_selected, false ) . '>' . $form_field_label . '</option>';
1270
- }
1271
- }
1272
- echo '
1273
- </select>
1274
- <a href="javascript:void(0)" class="remove-exclude-field button-secondary" title="' . __( 'Remove', 'iubenda' ) . '">-</a>
1275
- </td>
1276
- <td></td>
1277
- </tr>';
1278
-
1279
- $index++;
1280
- }
1281
- }
1282
-
1283
- echo '
1284
- <tr class="submit-field"><td colspan="2"><a href="javascript:void(0)" class="add-exclude-field button-secondary">' . __( 'Add New Exclude', 'iubenda' ) . '</a></td></tr>
1285
- </tbody>
1286
- </table>
1287
- </td>
1288
- </tr>
1289
- </tbody>
1290
- </table>
1291
- </div>
1292
- </div>
1293
- <div id="legal-notices" class="postbox">
1294
- <h3 class="hndle ui-sortable-handle"><span>' . __( 'Legal Notices', 'iubenda' ) . '</span></h3>
1295
- <div class="inside">
1296
- <table class="widefat">
1297
- <tbody>
1298
- <tr>
1299
- <td class="label table-label">
1300
- <h4>' . __( 'Legal documents', 'iubenda' ) . '</h4>
1301
- <p class="description">' . __( 'In general, it\'s important that you declare which legal documents are being agreed upon when each consent is collected. However, if you use iubenda for your legal documents, it is *required* that you identify the documents by selecting them here.', 'iubenda' ) . '</p>
1302
- </td>
1303
- <td>
1304
- <table class="widefat legal_notices-table">
1305
- <thead>
1306
- <td class="label">' . __( 'Identifier', 'iubenda' ) . '</td>
1307
- <td class="label"></td>
1308
- </thead>
1309
- <tbody>';
1310
-
1311
- // default identifiers
1312
- foreach ( $this->legal_notices as $index => $field_name ) {
1313
- echo '
1314
- <tr class="legal_notices-field default-field">
1315
- <td>' . ( $index === 0 ? '<p class="description">' . __( 'Please select each legal document available on your site.', 'iubenda' ) . '</p>' : '' ) . '<label for="legal_notices-default-field=' . $index . '"><input id="legal_notices-default-field=' . $index . '" type="checkbox" value="' . $field_name . '" name="legal_notices[' . $index . '][field]"' . checked( in_array( $field_name, $legal_notices, true ), true, false ) . 'placeholder="' . __( 'Enter field name', 'iubenda' ) . '" />' . $field_name . '</label></td>
1316
- <td></td>
1317
- </tr>';
1318
- }
1319
-
1320
- $index++;
1321
-
1322
- // custom identifiers
1323
- echo '
1324
- <tr id="legal_notices-field-template" class="template-field" style="display: none;">
1325
- <td><input type="text" class="regular-text" value="" name="legal_notices[__LEGAL_NOTICE_ID__][field]" placeholder="' . __( 'Enter field name', 'iubenda' ) . '" /> <a href="javascript:void(0)" class="remove-legal_notices-field button-secondary" title="' . __( 'Remove', 'iubenda' ) . '">-</a></td>
1326
- <td></td>
1327
- </tr>';
1328
-
1329
- echo '
1330
- <tr>
1331
- <td colspan="2"><p class="description" style="margin-bottom: 0;">' . __( 'Alternatively, you may add your own custom document identifiers.', 'iubenda' ) . '</p></td>
1332
- </tr>';
1333
-
1334
- if ( $legal_notices ) {
1335
- foreach ( $legal_notices as $field_name ) {
1336
- if ( in_array( $field_name, $this->legal_notices, true ) )
1337
- continue;
1338
-
1339
- echo '
1340
- <tr class="legal_notices-field options-field">
1341
- <td><input type="text" class="regular-text" value="' . $field_name . '" name="legal_notices[' . $index . '][field]" placeholder="' . __( 'Enter field name', 'iubenda' ) . '" /> <a href="javascript:void(0)" class="remove-legal_notices-field button-secondary" title="' . __( 'Remove', 'iubenda' ) . '">-</a></td>
1342
- <td></td>
1343
- </tr>';
1344
-
1345
- $index++;
1346
- }
1347
- }
1348
-
1349
- echo '
1350
- <tr class="submit-field"><td colspan="2"><a href="javascript:void(0)" class="add-legal_notices-field button-secondary">' . __( 'Add New Document', 'iubenda' ) . '</a></td></tr>';
1351
- echo '
1352
- </tbody>
1353
- </table>
1354
- </td>
1355
- </tr>
1356
- </tbody>
1357
- </table>
1358
- </div>
1359
- </div>
1360
- </div>
1361
- </div>
1362
- </div>
1363
- </div>
1364
- <div class="clear"></div>';
1365
-
1366
- // echo '<pre>'; print_r( $form ); echo '</pre>';
1367
- }
1368
-
1369
- /**
1370
- * Save cookie solution options.
1371
- *
1372
- * @return void
1373
- */
1374
- public function save_cookie_law_options( $input ) {
1375
- if ( ! current_user_can( apply_filters( 'iubenda_cookie_law_cap', 'manage_options' ) ) )
1376
- return $input;
1377
-
1378
- // save options
1379
- if ( isset( $_POST['save_iubenda_options'] ) ) {
1380
- $input['parse'] = (bool) isset( $input['parse'] );
1381
- $input['parser_engine'] = isset( $input['parser_engine'] ) && in_array( $input['parser_engine'], array( 'default', 'new' ) ) ? $input['parser_engine'] : iubenda()->defaults['cs']['parser_engine'];
1382
- $input['skip_parsing'] = (bool) isset( $input['skip_parsing'] );
1383
- $input['ctype'] = (bool) isset( $input['ctype'] );
1384
- $input['output_feed'] = (bool) isset( $input['output_feed'] );
1385
- $input['output_post'] = (bool) isset( $input['output_post'] );
1386
- $input['menu_position'] = isset( $input['menu_position'] ) && in_array( $input['menu_position'], array( 'topmenu', 'submenu' ) ) ? $input['menu_position'] : iubenda()->defaults['cs']['menu_position'];
1387
- $input['amp_support'] = (bool) isset( $input['amp_support'] );
1388
- $input['deactivation'] = (bool) isset( $input['deactivation'] );
1389
-
1390
- // multilang support
1391
- if ( iubenda()->multilang && ! empty( iubenda()->languages ) ) {
1392
- $iubenda_code = array();
1393
-
1394
- foreach ( iubenda()->languages as $lang_id => $lang_name ) {
1395
- $input['code_' . $lang_id] = $iubenda_code[$lang_id] = ! empty( $input['code_' . $lang_id] ) ? iubenda()->parse_code( $input['code_' . $lang_id] ) : '';
1396
-
1397
- // handle default lang too
1398
- if ( $lang_id == iubenda()->lang_default ) {
1399
- $input['code_default'] = ! empty( $input['code_' . $lang_id] ) ? iubenda()->parse_code( $input['code_' . $lang_id] ) : iubenda()->options['cs']['code_default'];
1400
- }
1401
- }
1402
- } else {
1403
- $iubenda_code = '';
1404
-
1405
- $input['code_default'] = $iubenda_code = ! empty( $input['code_default'] ) ? iubenda()->parse_code( $input['code_default'] ) : '';
1406
- }
1407
-
1408
- // generate amp template file
1409
- if ( isset( $input['amp_support'] ) ) {
1410
- $template_done = false;
1411
-
1412
- if ( ! empty( $iubenda_code ) ) {
1413
- if ( is_array( $iubenda_code ) ) {
1414
- $template_done = array();
1415
-
1416
- foreach ( $iubenda_code as $lang => $code ) {
1417
- $template_done[$lang] = (bool) iubenda()->AMP->generate_amp_template( $code, $lang );
1418
- }
1419
- } else {
1420
- $template_done = (bool) iubenda()->AMP->generate_amp_template( $iubenda_code );
1421
- }
1422
- }
1423
-
1424
- $input['amp_template_done'] = $template_done;
1425
-
1426
- if ( is_array( $input['amp_template'] ) ) {
1427
- foreach ( $input['amp_template'] as $lang => $template ) {
1428
- $input['amp_template'][$lang] = esc_url( $template );
1429
- }
1430
- } else {
1431
- $input['amp_template'] = esc_url( $input['amp_template'] );
1432
- }
1433
- }
1434
-
1435
- // scripts
1436
- if ( ! empty( $input['custom_scripts'] ) && ! empty( $input['custom_scripts']['script'] ) && ! empty( $input['custom_scripts']['type'] ) ) {
1437
- $scripts = array();
1438
-
1439
- // first field is template
1440
- if ( count( $input['custom_scripts']['script'] ) > 1 ) {
1441
- foreach ( $input['custom_scripts']['script'] as $number => $script ) {
1442
- $trimmed = trim( $script );
1443
-
1444
- if ( $trimmed !== '' )
1445
- $scripts[$trimmed] = (int) $input['custom_scripts']['type'][$number];
1446
- }
1447
- }
1448
-
1449
- $input['custom_scripts'] = $scripts;
1450
- } else
1451
- $input['custom_scripts'] = array();
1452
-
1453
- // iframes
1454
- if ( ! empty( $input['custom_iframes'] ) && ! empty( $input['custom_iframes']['iframe'] ) && ! empty( $input['custom_iframes']['type'] ) ) {
1455
- $iframes = array();
1456
-
1457
- // first field is template
1458
- if ( count( $input['custom_iframes']['iframe'] ) > 1 ) {
1459
- foreach ( $input['custom_iframes']['iframe'] as $number => $iframe ) {
1460
- $trimmed = trim( $iframe );
1461
-
1462
- if ( $trimmed !== '' )
1463
- $iframes[$trimmed] = (int) $input['custom_iframes']['type'][$number];
1464
- }
1465
- }
1466
-
1467
- $input['custom_iframes'] = $iframes;
1468
- } else
1469
- $input['custom_iframes'] = array();
1470
-
1471
- add_settings_error( 'cs_settings_errors', 'iub_cs_settings_updated', __( 'Settings saved.', 'iubenda' ), 'updated' );
1472
- // reset options
1473
- } elseif ( isset( $_POST['reset_iubenda_options'] ) ) {
1474
- $input = iubenda()->defaults['cs'];
1475
-
1476
- // multilang support
1477
- if ( iubenda()->multilang && ! empty( iubenda()->languages ) ) {
1478
- foreach ( iubenda()->languages as $lang_id => $lang_name ) {
1479
- $input['code_' . $lang_id] = '';
1480
- }
1481
- }
1482
-
1483
- add_settings_error( 'cs_settings_errors', 'iub_cs_settings_restored', __( 'Settings restored to defaults.', 'iubenda' ), 'updated' );
1484
- }
1485
-
1486
- return $input;
1487
- }
1488
-
1489
- /**
1490
- * Save consent solution options.
1491
- *
1492
- * @return void
1493
- */
1494
- public function save_consent_options( $input ) {
1495
-
1496
- if ( ! current_user_can( apply_filters( 'iubenda_cookie_law_cap', 'manage_options' ) ) )
1497
- return $input;
1498
-
1499
- // save options
1500
- if ( isset( $_POST['save_consent_options'] ) ) {
1501
- $input['public_api_key'] = isset( $input['public_api_key'] ) ? esc_attr( $input['public_api_key'] ) : '';
1502
-
1503
- add_settings_error( 'cons_settings_errors', 'iub_cons_settings_updated', __( 'Settings saved.', 'iubenda' ), 'updated' );
1504
- // reset options
1505
- } elseif ( isset( $_POST['reset_consent_options'] ) ) {
1506
- $input = iubenda()->defaults['cons'];
1507
-
1508
- add_settings_error( 'cons_settings_errors', 'iub_cons_settings_restored', __( 'Settings restored to defaults.', 'iubenda' ), 'updated' );
1509
- }
1510
-
1511
- return $input;
1512
- }
1513
-
1514
- /**
1515
- * Process the bulk actions
1516
- *
1517
- * @return void
1518
- */
1519
- public function process_actions() {
1520
- global $pagenow;
1521
-
1522
- $page = ! empty( $_POST['option_page'] ) ? esc_attr( $_POST['option_page'] ) : ( ! empty( $_GET['page'] ) ? esc_attr( $_GET['page'] ) : '' );
1523
- $id = isset( $_REQUEST['form_id'] ) ? ( is_array( $_REQUEST['form_id'] ) ? array_map( 'ansint', $_REQUEST['form_id'] ) : absint( $_REQUEST['form_id'] ) ) : false;
1524
- $tab_key = ! empty( $_GET['tab'] ) ? esc_attr( $_GET['tab'] ) : 'cs';
1525
-
1526
- if ( ! $page )
1527
- return;
1528
-
1529
- // get redirect url
1530
- if ( iubenda()->options['cs']['menu_position'] === 'submenu' && $pagenow === 'admin.php' ) {
1531
- // sub menu
1532
- $redirect_to = admin_url( 'options-general.php?page=iubenda&tab=' . $tab_key );
1533
- } else {
1534
- // top menu
1535
- $redirect_to = admin_url( 'admin.php?page=iubenda&tab=' . $tab_key );
1536
- }
1537
-
1538
- // add comments cookie option notice
1539
- if ( $tab_key != 'cs' && ! empty( iubenda()->options['cons']['public_api_key'] ) ) {
1540
- $cookies_enabled = get_option( 'show_comments_cookies_opt_in' );
1541
-
1542
- if ( ! $cookies_enabled ) {
1543
- $this->add_notice( 'iub_comment_cookies_disabled', sprintf( __( 'Please enable comments cookies opt-in checkbox in the <a href="%s" target="_blank">Discussion settings</a>.', 'iubenda' ), esc_url( admin_url( 'options-discussion.php' ) ) ), 'notice' );
1544
- }
1545
- }
1546
-
1547
- $result = null;
1548
-
1549
- switch ( $this->action ) {
1550
- case 'autodetect' :
1551
- $result = iubenda()->forms->autodetect_forms();
1552
-
1553
- // new forms notice
1554
- if ( ! empty( $result['new'] ) )
1555
- $this->add_notice( 'iub_autodetect_success', sprintf( _n( '%d form detected successfully.', '%d forms detected successfully.', count( $result['new'] ), 'iubenda' ), $result ), 'success' );
1556
-
1557
- // forms changed notice
1558
- if ( ! empty( $result['updated'] ) )
1559
- $this->add_notice( 'iub_autodetect_success', sprintf( _n( '%d form change detected.', '%d form changes detected.', count( $result['updated'] ), 'iubenda' ), $result ), 'success' );
1560
-
1561
- // no changes notice
1562
- if ( empty( $result['new'] ) && empty( $result['updated'] ) )
1563
- $this->add_notice( 'iub_autodetect_success', __( 'No forms or form changes detected.', 'iubenda' ), 'error' );
1564
-
1565
- // make sure it's current host location
1566
- wp_safe_redirect( $redirect_to );
1567
- exit;
1568
-
1569
- break;
1570
-
1571
- case 'save' :
1572
- if ( ! $id )
1573
- return;
1574
-
1575
- $form = iubenda()->forms->get_form( $id );
1576
-
1577
- if ( $form->ID != $id )
1578
- return;
1579
-
1580
- $status = isset( $_POST['status'] ) && in_array( $_POST['status'], array_keys( iubenda()->forms->statuses ) ) ? esc_attr( $_POST['status'] ) : 'publish';
1581
- $subject = isset( $_POST['subject'] ) && is_array( $_POST['subject'] ) ? array_map( 'esc_attr', $_POST['subject'] ) : array();
1582
- $preferences = array();
1583
- $exclude = array();
1584
- $legal_notices = array();
1585
-
1586
- $preferences_raw = isset( $_POST['preferences'] ) && is_array( $_POST['preferences'] ) ? array_map( array( $this, 'array_map_callback' ), $_POST['preferences'] ) : array();
1587
- $exclude_raw = isset( $_POST['exclude'] ) && is_array( $_POST['exclude'] ) ? array_map( array( $this, 'array_map_callback' ), $_POST['exclude'] ) : array();
1588
- $legal_notices_raw = isset( $_POST['legal_notices'] ) && is_array( $_POST['legal_notices'] ) ? array_map( array( $this, 'array_map_callback' ), $_POST['legal_notices'] ) : array();
1589
-
1590
- // format preferences data
1591
- if ( ! empty( $preferences_raw ) && is_array( $preferences_raw ) ) {
1592
- foreach ( $preferences_raw as $index => $data ) {
1593
- if ( ! empty( $data['field'] ) && ! empty( $data['value'] ) )
1594
- $preferences[ sanitize_key( $data['field'] ) ] = $data['value'];
1595
- }
1596
- }
1597
-
1598
- // format exclude data
1599
- if ( ! empty( $exclude_raw ) && is_array( $exclude_raw ) ) {
1600
- foreach ( $exclude_raw as $index => $data ) {
1601
- if ( ! empty( $data['field'] ) )
1602
- $exclude[] = $data['field'];
1603
- }
1604
- }
1605
-
1606
- // format legal notices data
1607
- if ( ! empty( $legal_notices_raw ) && is_array( $legal_notices_raw ) ) {
1608
- foreach ( $legal_notices_raw as $index => $data ) {
1609
- if ( ! empty( $data['field'] ) )
1610
- $legal_notices[] = $data['field'];
1611
- }
1612
- }
1613
-
1614
- // form first save, update status to mapped automatically
1615
- if ( empty( $form->form_subject ) && empty( $form->form_preferences ) ) {
1616
- $status = 'mapped';
1617
- }
1618
-
1619
- // echo '<pre>'; print_r( $_POST ); echo '</pre>'; exit;
1620
-
1621
- // bail if empty fields
1622
- if ( empty( $subject ) || empty( $preferences ) ) {
1623
- $this->add_notice( 'iub_form_fields_missing', __( 'Form saving failed. Please fill the Subject and Preferences fields.', 'iubenda' ), 'error' );
1624
- return;
1625
- }
1626
-
1627
- $args = array(
1628
- 'ID' => $form->ID,
1629
- 'status' => $status,
1630
- 'object_type' => $form->object_type,
1631
- 'object_id' => $form->object_id,
1632
- 'form_source' => $form->form_source,
1633
- 'form_title' => $form->post_title,
1634
- 'form_date' => $form->post_modified,
1635
- 'form_fields' => $form->form_fields,
1636
- 'form_subject' => $subject,
1637
- 'form_preferences' => $preferences,
1638
- 'form_exclude' => $exclude,
1639
- 'form_legal_notices' => $legal_notices
1640
- );
1641
-
1642
- $result = iubenda()->forms->save_form( $args );
1643
-
1644
- if ( $result ) {
1645
- // form save, inform about form status update
1646
- if ( empty( $form->form_subject ) && empty( $form->form_preferences ) ) {
1647
- $this->add_notice( 'iub_form_saved', __( 'Form saved successfully - form status changed to Mapped.', 'iubenda' ), 'success' );
1648
- // form update
1649
- } else {
1650
- $this->add_notice( 'iub_form_updated', __( 'Form updated successfully.', 'iubenda' ), 'success' );
1651
- }
1652
- } else {
1653
- $this->add_notice( 'iub_form_failed', __( 'Form saving failed.', 'iubenda' ), 'error' );
1654
- }
1655
-
1656
- break;
1657
-
1658
- case 'delete' :
1659
- if ( ! $id )
1660
- return;
1661
-
1662
- $form = iubenda()->forms->get_form( $id );
1663
-
1664
- if ( empty( $form ) )
1665
- return;
1666
-
1667
- $result = iubenda()->forms->delete_form( $id );
1668
-
1669
- if ( $result )
1670
- $this->add_notice( 'iub_form_deleted', __( 'Form deleted successfully.', 'iubenda' ), 'success' );
1671
- else
1672
- $this->add_notice( 'iub_form_delete_failed', __( 'Form delete failed.', 'iubenda' ), 'error' );
1673
-
1674
- // make sure it's current host location
1675
- wp_safe_redirect( $redirect_to );
1676
- exit;
1677
-
1678
- break;
1679
-
1680
- case 'disable_skip_parsing' :
1681
-
1682
- // disable skip parsing option
1683
- $options = iubenda()->options['cs'];
1684
- $options['skip_parsing'] = false;
1685
-
1686
- update_option( 'iubenda_cookie_law_solution', $options );
1687
-
1688
- $this->add_notice( 'iub_settings_updated', __( 'Settings saved.', 'iubenda' ), 'success' );
1689
-
1690
- // make sure it's current host location
1691
- wp_safe_redirect( $redirect_to );
1692
- exit;
1693
-
1694
- break;
1695
-
1696
- default :
1697
- return;
1698
- }
1699
-
1700
- if ( ! empty ( $result ) ) {
1701
- //
1702
- } else {
1703
- //
1704
- }
1705
- }
1706
-
1707
- /**
1708
- * Add admin notice.
1709
- *
1710
- * @param mixed $message
1711
- * @param string $notice_type
1712
- */
1713
- public function add_notice( $key, $message, $notice_type = 'notice' ) {
1714
- $key = ! empty( $key ) ? sanitize_key( $key ) : '';
1715
- $message = ! empty( $message ) ? wp_kses_post( $message ) : '';
1716
- $notice_type = ! empty( $notice_type ) && in_array( $notice_type, $this->notice_types ) ? $notice_type : 'notice';
1717
-
1718
- if ( ! $key || ! $message )
1719
- return;
1720
-
1721
- $notices = get_transient( 'iubenda_dashboard_notices' );
1722
- $delay = MINUTE_IN_SECONDS * 2;
1723
-
1724
- if ( empty( $notices ) || ! array_key_exists( $key, $notices[$notice_type] ) ) {
1725
- $notices[$notice_type][$key] = $message;
1726
-
1727
- set_transient( 'iubenda_dashboard_notices', $notices, $delay );
1728
- }
1729
- }
1730
-
1731
- /**
1732
- * Display admin notices.
1733
- *
1734
- * @return mixed
1735
- */
1736
- public function print_notices() {
1737
- $notices = get_transient( 'iubenda_dashboard_notices' );
1738
- $notices_array = array();
1739
-
1740
- foreach ( $this->notice_types as $notice_type ) {
1741
- if ( $this->notice_count( $notices, $notice_type ) > 0 ) {
1742
- echo '<div class="notice notice-' . ( $notice_type === 'notice' ? 'info' : $notice_type ) . ' below-h2 is-dismissible">';
1743
-
1744
- foreach ( $notices[$notice_type] as $key => $notice ) {
1745
- echo '<p><strong>' . wp_kses_post( $notice ) . '</strong></p>';
1746
- }
1747
-
1748
- echo '<button type="button" class="notice-dismiss"><span class="screen-reader-text">' . __( 'Dismiss this notice.' ) . '</span></button>';
1749
-
1750
- echo '</div>';
1751
- }
1752
- }
1753
-
1754
- delete_transient( 'iubenda_dashboard_notices' );
1755
- }
1756
-
1757
- /**
1758
- * Count notices function.
1759
- *
1760
- * @param string $notice_type
1761
- * @return int
1762
- */
1763
- public function notice_count( $all_notices = array(), $notice_type = '' ) {
1764
- $notice_count = 0;
1765
-
1766
- if ( isset( $all_notices[$notice_type] ) ) {
1767
- $notice_count = absint( sizeof( $all_notices[$notice_type] ) );
1768
- } elseif ( empty( $notice_type ) ) {
1769
- foreach ( $all_notices as $notices ) {
1770
- $notice_count += absint( sizeof( $all_notices ) );
1771
- }
1772
- }
1773
-
1774
- return $notice_count;
1775
- }
1776
-
1777
- /**
1778
- * Adjust highlighted menu.
1779
- *
1780
- * @param type $file
1781
- * @return type
1782
- */
1783
- public function submenu_file( $submenu_file, $parent_file ) {
1784
- global $menu, $submenu;
1785
-
1786
- if ( $parent_file == 'iubenda' ) {
1787
- $tab_key = ! empty( $_GET['tab'] ) ? esc_attr( $_GET['tab'] ) : 'cs';
1788
-
1789
- if ( $tab_key == 'cons' ) {
1790
- $submenu_file = 'admin.php?page=iubenda&tab=cons';
1791
- $submenu['iubenda'][1][2] = 'admin.php?page=iubenda&tab=cons';
1792
- }
1793
- }
1794
-
1795
- return $submenu_file;
1796
- }
1797
-
1798
- /**
1799
- * Sanitize array helper function.
1800
- *
1801
- * @param array $array
1802
- * @return array
1803
- */
1804
- public function array_map_callback( $array ) {
1805
- if ( ! is_array( $array ) )
1806
- return array();
1807
-
1808
- return array_map( 'esc_attr', $array );
1809
- }
1810
-
1811
- }
1
+ <?php
2
+ // exit if accessed directly
3
+ if ( ! defined( 'ABSPATH' ) )
4
+ exit;
5
+
6
+ /**
7
+ * iubenda_Settings class.
8
+ *
9
+ * @class Post_Views_Counter_Settings
10
+ */
11
+ class iubenda_Settings {
12
+
13
+ public $tabs = array();
14
+ public $action = '';
15
+ public $links = array();
16
+ public $notice_types = array( 'error', 'success', 'notice' );
17
+ public $subject_fields = array();
18
+
19
+ public function __construct() {
20
+ // actions
21
+ add_action( 'after_setup_theme', array( $this, 'load_defaults' ) );
22
+ add_action( 'admin_init', array( $this, 'register_options' ) );
23
+ add_action( 'admin_init', array( $this, 'update_plugin' ), 9 );
24
+ add_action( 'admin_init', array( $this, 'admin_page_redirect' ), 20 );
25
+ add_action( 'admin_init', array( $this, 'process_actions' ), 20 );
26
+ add_action( 'admin_init', array( $this, 'maybe_show_notice' ) );
27
+ add_action( 'admin_menu', array( $this, 'admin_menu_options' ) );
28
+ add_action( 'admin_notices', array( $this, 'settings_errors' ) );
29
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
30
+ add_action( 'admin_print_styles', array( $this, 'admin_print_styles' ) );
31
+ // add_action( 'admin_footer-options-discussion.php', array( $this, 'admin_footer' ) );
32
+ add_action( 'wp_ajax_iubenda_dismiss_notice', array( $this, 'dismiss_notice' ) );
33
+
34
+ // filters
35
+ add_filter( 'submenu_file', array( $this, 'submenu_file' ), 10, 2 );
36
+ }
37
+
38
+ /**
39
+ * Load default settings.
40
+ */
41
+ public function load_defaults() {
42
+ $this->subject_fields = array(
43
+ 'id' => __( 'string', 'iubenda' ),
44
+ 'email' => __( 'string', 'iubenda' ),
45
+ 'first_name' => __( 'string', 'iubenda' ),
46
+ 'last_name' => __( 'string', 'iubenda' ),
47
+ 'full_name' => __( 'string', 'iubenda' ),
48
+ // 'verified' => __( 'boolean', 'iubenda' ),
49
+ );
50
+
51
+ $this->legal_notices = array(
52
+ 'privacy_policy',
53
+ 'cookie_policy',
54
+ 'terms'
55
+ );
56
+
57
+ $this->tabs = array(
58
+ 'cs' => array(
59
+ 'name' => __( 'Cookie Solution', 'iubenda' ),
60
+ 'key' => 'iubenda_cookie_law_solution',
61
+ 'submit' => 'save_iubenda_options',
62
+ 'reset' => 'reset_iubenda_options'
63
+ ),
64
+ 'cons' => array(
65
+ 'name' => __( 'Consent Solution', 'iubenda' ),
66
+ 'key' => 'iubenda_consent_solution',
67
+ 'submit' => 'save_consent_options',
68
+ 'reset' => 'reset_consent_options'
69
+ )
70
+ );
71
+
72
+ $this->tag_types = array(
73
+ 0 => __( 'Not set', 'iubenda' ),
74
+ 1 => __( 'Strictly necessary', 'iubenda' ),
75
+ 2 => __( 'Basic interactions & functionalities', 'iubenda' ),
76
+ 3 => __( 'Experience enhancement', 'iubenda' ),
77
+ 4 => __( 'Analytics', 'iubenda' ),
78
+ 5 => __( 'Targeting & Advertising', 'iubenda' )
79
+ );
80
+
81
+ $links = array(
82
+ 'en' => array(
83
+ 'iab' => 'https://www.iubenda.com/en/help/7440-enable-preference-management-iab-framework',
84
+ 'guide' => 'https://www.iubenda.com/en/cookie-solution',
85
+ 'plugin_page' => 'https://www.iubenda.com/en/help/posts/1215',
86
+ 'generating_code' => 'https://www.iubenda.com/en/help/1177-cookie-solution-getting-started',
87
+ 'support_forum' => 'https://support.iubenda.com/support/home',
88
+ 'documentation' => 'https://www.iubenda.com/en/help/posts/1215'
89
+ ),
90
+ 'it' => array(
91
+ 'iab' => 'https://www.iubenda.com/en/help/7440-enable-preference-management-iab-framework',
92
+ 'guide' => 'https://www.iubenda.com/it/cookie-solution',
93
+ 'plugin_page' => 'https://www.iubenda.com/it/help/posts/810',
94
+ 'generating_code' => 'https://www.iubenda.com/it/help/680-introduzione-cookie-solution',
95
+ 'support_forum' => 'https://support.iubenda.com/support/home',
96
+ 'documentation' => 'https://www.iubenda.com/it/help/posts/810',
97
+ )
98
+ );
99
+
100
+ $locale = explode( '_', get_locale() );
101
+ $locale_code = $locale[0];
102
+
103
+ // assign links
104
+ $this->links = in_array( $locale_code, array_keys( $links ) ) ? $links[$locale_code] : $links['en'];
105
+
106
+ // handle actions
107
+ if ( ! empty( $_POST['save'] ) ) {
108
+ // update item action
109
+ $this->action = 'save';
110
+ } else {
111
+ $this->action = isset( $_REQUEST['action'] ) && -1 != $_REQUEST['action'] ? esc_attr( $_REQUEST['action'] ) : '';
112
+ $this->action = isset( $_REQUEST['action2'] ) && -1 != $_REQUEST['action2'] ? esc_attr( $_REQUEST['action2'] ) : $this->action;
113
+ }
114
+ }
115
+
116
+ /**
117
+ * Register plugin options.
118
+ *
119
+ * @return void
120
+ */
121
+ public function register_options() {
122
+ register_setting( 'iubenda_cookie_law_solution', 'iubenda_cookie_law_solution', array( $this, 'save_cookie_law_options' ) );
123
+
124
+ add_settings_section( 'iubenda_cookie_law_solution', '', '', 'iubenda_cookie_law_solution' );
125
+ add_settings_field( 'iub_code', __( 'Code', 'iubenda' ), array( $this, 'iub_code' ), 'iubenda_cookie_law_solution', 'iubenda_cookie_law_solution' );
126
+ add_settings_field( 'iub_amp_support', __( 'Google AMP', 'iubenda' ), array( $this, 'iub_amp_support' ), 'iubenda_cookie_law_solution', 'iubenda_cookie_law_solution' );
127
+ add_settings_field( 'iub_parse', __( 'Script blocking', 'iubenda' ), array( $this, 'iub_parse' ), 'iubenda_cookie_law_solution', 'iubenda_cookie_law_solution' );
128
+ add_settings_field( 'iub_custom_scripts', __( 'Custom scripts', 'iubenda' ), array( $this, 'iub_custom_scripts' ), 'iubenda_cookie_law_solution', 'iubenda_cookie_law_solution' );
129
+ add_settings_field( 'iub_ctype', __( 'Content type', 'iubenda' ), array( $this, 'iub_ctype' ), 'iubenda_cookie_law_solution', 'iubenda_cookie_law_solution' );
130
+ add_settings_field( 'iub_output_feed', __( 'RSS feed', 'iubenda' ), array( $this, 'iub_output_feed' ), 'iubenda_cookie_law_solution', 'iubenda_cookie_law_solution' );
131
+ add_settings_field( 'iub_output_post', __( 'POST requests', 'iubenda' ), array( $this, 'iub_output_post' ), 'iubenda_cookie_law_solution', 'iubenda_cookie_law_solution' );
132
+ add_settings_field( 'iub_menu_position', __( 'Menu position', 'iubenda' ), array( $this, 'iub_menu_position' ), 'iubenda_cookie_law_solution', 'iubenda_cookie_law_solution' );
133
+ add_settings_field( 'iub_deactivation', __( 'Deactivation', 'iubenda' ), array( $this, 'iub_deactivation' ), 'iubenda_cookie_law_solution', 'iubenda_cookie_law_solution' );
134
+
135
+ // forms list
136
+ if ( ! in_array( $this->action, array( 'save', 'edit' ) ) ) {
137
+ register_setting( 'iubenda_consent_solution', 'iubenda_consent_solution', array( $this, 'save_consent_options' ) );
138
+ add_settings_section( 'iubenda_consent_solution', __( 'Forms', 'iubenda' ), '', 'iubenda_consent_solution' );
139
+ add_settings_field( 'iub_public_api_key', __( 'Public Api Key', 'iubenda' ), array( $this, 'iub_public_api_key' ), 'iubenda_consent_solution', 'iubenda_consent_solution' );
140
+ // only if api key is given
141
+ if ( ! empty( iubenda()->options['cons']['public_api_key'] ) )
142
+ add_settings_section( 'iubenda_consent_forms', __( 'Field Mapping', 'iubenda' ), array( $this, 'iubenda_consent_forms' ), 'iubenda_consent_solution' );
143
+ // single form
144
+ } else {
145
+ register_setting( 'iubenda_consent_solution', 'iubenda_consent_forms' );
146
+ add_settings_section( 'iubenda_consent_form', __( 'Field Mapping', 'iubenda' ), array( $this, 'iubenda_consent_form' ), 'iubenda_consent_solution' );
147
+ }
148
+ }
149
+
150
+ /**
151
+ * Display errors and notices.
152
+ *
153
+ * @global string $pagenow
154
+ */
155
+ public function settings_errors() {
156
+ global $pagenow;
157
+
158
+ // force display notices in top menu settings page
159
+ if ( $pagenow == 'options-general.php' )
160
+ return;
161
+
162
+ $tab_key = ! empty( $_GET['tab'] ) ? esc_attr( $_GET['tab'] ) : 'cs';
163
+
164
+ settings_errors( "{$tab_key}_settings_errors" );
165
+ }
166
+
167
+ /**
168
+ * Add submenu.
169
+ *
170
+ * @return void
171
+ */
172
+ public function admin_menu_options() {
173
+ if ( iubenda()->options['cs']['menu_position'] === 'submenu' ) {
174
+ // sub menu
175
+ add_submenu_page(
176
+ 'options-general.php', 'iubenda', 'iubenda', apply_filters( 'iubenda_cookie_law_cap', 'manage_options' ), 'iubenda', array( $this, 'options_page' )
177
+ );
178
+ } else {
179
+ // top menu
180
+ add_menu_page(
181
+ 'iubenda', 'iubenda', apply_filters( 'iubenda_cookie_law_cap', 'manage_options' ), 'iubenda', array( $this, 'options_page' ), 'none'
182
+ );
183
+ add_submenu_page( 'iubenda', __( 'Cookie Solution', 'iubenda' ), __( 'Cookie Solution', 'iubenda' ), apply_filters( 'iubenda_cookie_law_cap', 'manage_options' ), 'iubenda', array( $this, 'options_page' ) );
184
+ add_submenu_page( 'iubenda', __( 'Consent Solution', 'iubenda' ), __( 'Consent Solution', 'iubenda' ), apply_filters( 'iubenda_cookie_law_cap', 'manage_options' ), 'iubenda&tab=cons', array( $this, 'options_page' ) );
185
+ }
186
+ }
187
+
188
+ /**
189
+ * Load admin scripts and styles.
190
+ *
191
+ * @param string $page
192
+ * @return void
193
+ */
194
+ public function admin_enqueue_scripts( $page ) {
195
+ wp_enqueue_style( 'iubenda-admin', IUBENDA_PLUGIN_URL . '/css/admin.css' );
196
+
197
+ if ( ! in_array( $page, array( 'toplevel_page_iubenda', 'settings_page_iubenda' ) ) )
198
+ return;
199
+
200
+ wp_enqueue_script(
201
+ 'iubenda-admin', IUBENDA_PLUGIN_URL . '/js/admin.js', array( 'jquery' )
202
+ );
203
+
204
+ $args = array(
205
+ 'formId' => 0,
206
+ 'deleteForm' => __( 'Are you sure you want to delete this form?', 'iubenda' )
207
+ );
208
+
209
+ // get form data on edit screen
210
+ if ( in_array( $this->action, array( 'edit' ) ) ) {
211
+ $form_id = ! empty( $_GET['form_id'] ) ? absint( $_GET['form_id'] ) : 0;
212
+ $form = ! empty( $form_id ) ? iubenda()->forms->get_form( $form_id ) : array();
213
+
214
+ $args['formId'] = $form_id;
215
+ }
216
+
217
+ wp_localize_script(
218
+ 'iubenda-admin',
219
+ 'iubAdminArgs',
220
+ json_encode( $args )
221
+ );
222
+ }
223
+
224
+ /**
225
+ * Load admin style inline, for menu icon only.
226
+ *
227
+ * @return mixed
228
+ */
229
+ public function admin_print_styles() {
230
+ echo '
231
+ <style>
232
+ a.toplevel_page_iubenda .wp-menu-image {
233
+ background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj48c3ZnIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHZpZXdCb3g9IjAgMCAyMzIgNTAzIiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHhtbDpzcGFjZT0icHJlc2VydmUiIHhtbG5zOnNlcmlmPSJodHRwOi8vd3d3LnNlcmlmLmNvbS8iIHN0eWxlPSJmaWxsLXJ1bGU6ZXZlbm9kZDtjbGlwLXJ1bGU6ZXZlbm9kZDtzdHJva2UtbGluZWpvaW46cm91bmQ7c3Ryb2tlLW1pdGVybGltaXQ6MS40MTQyMTsiPiAgICA8ZyB0cmFuc2Zvcm09Im1hdHJpeCgxLDAsMCwxLDEzNi4yNDcsMjY4LjgzMSkiPiAgICAgICAgPHBhdGggZD0iTTAsLTM1LjgxTC0zNi4zLDAuNDg5TC0zNi4zLDE0MC45NzhMMCwxNDAuOTc4TDAsLTM1LjgxWk0tMjAuOTM4LC0xMjkuODAyQy02LjI4NywtMTI5LjgwMiA1LjU4NywtMTQxLjU2NSA1LjU4NywtMTU2LjA2QzUuNTg3LC0xNzAuNTU2IC02LjI4NywtMTgyLjMwOCAtMjAuOTM4LC0xODIuMzA4Qy0zNS42LC0xODIuMzA4IC00Ny40NzQsLTE3MC41NTYgLTQ3LjQ3NCwtMTU2LjA2Qy00Ny40NzQsLTE0MS41NjUgLTM1LjYsLTEyOS44MDIgLTIwLjkzOCwtMTI5LjgwMk04OS4zNiwtMTU0LjQxNkM4OS4zNiwtMTI3LjgyNSA3OS41NzUsLTEwMy40OTkgNjMuMjY5LC04NC42NzJMODYuNjk0LDIyNi42MjhMLTEyMi43MjgsMjI2LjYyOEwtMTAwLjAyNCwtNzkuMjI5Qy0xMTkuMzUxLC05OC42NjggLTEzMS4yNDcsLTEyNS4xNTkgLTEzMS4yNDcsLTE1NC40MTZDLTEzMS4yNDcsLTIxNC4wODYgLTgxLjg3NCwtMjYyLjQzOCAtMjAuOTM4LC0yNjIuNDM4QzM5Ljk5OSwtMjYyLjQzOCA4OS4zNiwtMjE0LjA4NiA4OS4zNiwtMTU0LjQxNiIgc3R5bGU9ImZpbGw6d2hpdGU7ZmlsbC1ydWxlOm5vbnplcm87Ii8+ICAgIDwvZz48L3N2Zz4=);
234
+ background-position: center center;
235
+ background-repeat: no-repeat;
236
+ background-size: 7px auto;
237
+ }
238
+ </style>
239
+ ';
240
+ }
241
+
242
+ /**
243
+ * Highlight comments cookies opt-in checkbox option.
244
+ *
245
+ * @return mixed
246
+ */
247
+ public function admin_footer() {
248
+ if ( ! empty( $_GET['iub-highlight'] ) ) {
249
+ echo '
250
+ <style>
251
+ label[for=show_comments_cookies_opt_in] {
252
+ border: 1px dashed red;
253
+ }
254
+ </style>
255
+ ';
256
+ }
257
+ }
258
+
259
+ /**
260
+ * Redirect to the correct urle after switching menu position.
261
+ *
262
+ * @global string $pagenow
263
+ * @return void
264
+ */
265
+ public function admin_page_redirect() {
266
+ if ( ! empty( $_GET['settings-updated'] ) && ! empty( $_GET['page'] ) && in_array( $_GET['page'], array( 'iubenda' ) ) ) {
267
+ global $pagenow;
268
+
269
+ // no redirect by default
270
+ $redirect_to = false;
271
+
272
+ if ( iubenda()->options['cs']['menu_position'] === 'submenu' && $pagenow === 'admin.php' ) {
273
+ // sub menu
274
+ $redirect_to = admin_url( 'options-general.php?page=iubenda' );
275
+ } elseif ( iubenda()->options['cs']['menu_position'] === 'topmenu' && $pagenow === 'options-general.php' ) {
276
+ // top menu
277
+ $redirect_to = admin_url( 'admin.php?page=iubenda' );
278
+ }
279
+
280
+ if ( $redirect_to ) {
281
+ // make sure it's current host location
282
+ wp_safe_redirect( add_query_arg( 'settings-updated', true, $redirect_to ) );
283
+ exit;
284
+ }
285
+ }
286
+ }
287
+
288
+ /**
289
+ * Perform show notice on plugin installation/upgrade.
290
+ *
291
+ * @return void
292
+ */
293
+ public function maybe_show_notice() {
294
+ if ( ! current_user_can( 'install_plugins' ) )
295
+ return;
296
+
297
+ $current_update = 1;
298
+ $activation = (array) get_option( 'iubenda_activation_data', iubenda()->activation );
299
+
300
+ // delete_option( 'iubenda_activation_data' );
301
+ // echo '<pre>'; print_r( $activation ); echo '</pre>'; exit;
302
+
303
+ // get current time
304
+ $current_time = time();
305
+
306
+ if ( $activation['update_version'] < $current_update ) {
307
+ // check version, if update ver is lower than plugin ver, set update notice to true
308
+ $activation = array_merge( $activation, array( 'update_version' => $current_update, 'update_notice' => true ) );
309
+
310
+ // set activation date if not set
311
+ if ( $activation['update_date'] == false )
312
+ $activation = array_merge( $activation, array( 'update_date' => $current_time ) );
313
+
314
+ update_option( 'iubenda_activation_data', $activation );
315
+ }
316
+
317
+ // display current version notice
318
+ if ( $activation['update_notice'] === true ) {
319
+ // include notice js, only if needed
320
+ add_action( 'admin_print_scripts', array( $this, 'admin_inline_js' ), 999 );
321
+
322
+ // get activation date
323
+ $activation_date = $activation['update_date'];
324
+
325
+ // set delay in seconds
326
+ $delay = WEEK_IN_SECONDS * 2;
327
+
328
+ if ( (int) $activation['update_delay_date'] === 0 ) {
329
+ if ( $activation_date + $delay > $current_time )
330
+ $activation['update_delay_date'] = $activation_date + $delay;
331
+ else
332
+ $activation['update_delay_date'] = $current_time;
333
+
334
+ update_option( 'iubenda_activation_data', $activation );
335
+ }
336
+
337
+ if ( ( ! empty( $activation['update_delay_date'] ) ? (int) $activation['update_delay_date'] : $current_time ) <= $current_time ) {
338
+ // add notice
339
+ add_action( 'admin_notices', array( $this, 'show_notice' ) );
340
+ }
341
+ }
342
+ }
343
+
344
+ /**
345
+ * Display admin notices at iubenda settings.
346
+ */
347
+ public function show_notice() {
348
+ global $pagenow;
349
+
350
+ $display = true;
351
+ /*
352
+ $page = isset( $_GET['page'] ) ? esc_attr( $_GET['page'] ) : '';
353
+
354
+ if ( iubenda()->options['cs']['menu_position'] === 'submenu' && $page === 'iubenda' ) {
355
+ $display = true;
356
+ } elseif ( iubenda()->options['cs']['menu_position'] === 'topmenu' && $page === 'iubenda' ) {
357
+ $display = true;
358
+ }
359
+ */
360
+ ?>
361
+ <?php if ( $display ) { ?>
362
+ <div class="iubenda-notice notice is-dismissible">
363
+ <div>
364
+ <p class="step-1">
365
+ <span class="notice-question"><?php _e( 'Enjoying the iubenda Cookie & Consent Solution Plugin?', 'iubenda' ); ?></span>
366
+ <span class="notice-reply">
367
+ <a href="#" class="reply-yes"><?php _e( 'Yes', 'iubenda' ); ?></a>
368
+ <a href="#" class="reply-no"><?php _e( 'No', 'iubenda' ); ?></a>
369
+ </span>
370
+ </p>
371
+ <p class="step-2 step-yes">
372
+ <span class="notice-question"><?php _e( "Whew, what a relief!? We've worked countless hours to make this plugin as useful as possible - so we're pretty happy that you're enjoying it. While you here, would you mind leaving us a 5 star rating? It would really help us out.", 'iubenda' ); ?></span>
373
+ <span class="notice-reply">
374
+ <a href="https://wordpress.org/support/plugin/iubenda-cookie-law-solution/reviews/?filter=5" target="_blank" class="reply-yes"><?php _e( 'Sure!', 'iubenda' ); ?></a>
375
+ <a href="javascript:void(0)" class="reply-no"><?php _e( 'No thanks', 'iubenda' ); ?></a>
376
+ </span>
377
+ </p>
378
+ <p class="step-2 step-no">
379
+ <span class="notice-question"><?php _e( "We're sorry to hear that. Would you mind giving us some feedback?", 'iubenda' ); ?></span>
380
+ <span class="notice-reply">
381
+ <a href="https://iubenda.typeform.com/to/BXuSMZ" target="_blank" class="reply-yes"><?php _e( 'Ok sure!', 'iubenda' ); ?></a>
382
+ <a href="javascript:void(0)" class="reply-no"><?php _e( 'No thanks', 'iubenda' ); ?></a>
383
+ </span>
384
+ </p>
385
+ </div>
386
+ </div>
387
+ <?php } ?>
388
+ <?php
389
+ }
390
+
391
+ /**
392
+ * Print admin scripts.
393
+ *
394
+ * @return void
395
+ */
396
+ public function admin_inline_js() {
397
+ if ( ! current_user_can( 'install_plugins' ) )
398
+ return;
399
+
400
+ $delay = MONTH_IN_SECONDS * 6;
401
+ ?>
402
+ <script type="text/javascript">
403
+ ( function ( $ ) {
404
+ $( document ).ready( function () {
405
+ // step 1
406
+ $( '.iubenda-notice .step-1 a' ).on( 'click', function ( e ) {
407
+ e.preventDefault();
408
+
409
+ $( '.iubenda-notice .step-1' ).slideUp( 'fast' );
410
+
411
+ if ( $( e.target ).hasClass( 'reply-yes' ) ) {
412
+ $( '.iubenda-notice .step-2.step-yes' ).slideDown( 'fast' );
413
+ } else {
414
+ $( '.iubenda-notice .step-2.step-no' ).slideDown( 'fast' );
415
+ };
416
+ } );
417
+ // step 2
418
+ $( '.iubenda-notice.is-dismissible' ).on( 'click', '.notice-dismiss, .step-2 a', function ( e ) {
419
+ // console.log( $( e ) );
420
+
421
+ var delay = <?php echo $delay; ?>;
422
+
423
+ if ( $( e.target ).hasClass( 'reply-yes' ) ) {
424
+ delay = 0;
425
+ }
426
+
427
+ $.post( ajaxurl, {
428
+ action: 'iubenda_dismiss_notice',
429
+ delay: delay,
430
+ url: '<?php echo admin_url( 'admin-ajax.php' ); ?>',
431
+ iubenda_nonce: '<?php echo wp_create_nonce( 'iubenda_dismiss_notice' ); ?>'
432
+ } );
433
+
434
+ $( e.delegateTarget ).slideUp( 'fast' );
435
+ } );
436
+ } );
437
+ } )( jQuery );
438
+ </script>
439
+ <?php
440
+ }
441
+
442
+ /**
443
+ * Dismiss notice.
444
+ *
445
+ * @return void
446
+ */
447
+ public function dismiss_notice() {
448
+ $result = false;
449
+
450
+ if ( ! current_user_can( 'install_plugins' ) )
451
+ return $result;
452
+
453
+ $nonce = wp_verify_nonce( $_REQUEST['iubenda_nonce'], 'iubenda_dismiss_notice' );
454
+
455
+ if ( $nonce ) {
456
+ $delay = ! empty( $_REQUEST['delay'] ) ? absint( $_REQUEST['delay'] ) : 0;
457
+ $activation = (array) get_option( 'iubenda_activation_data', iubenda()->activation );
458
+
459
+ // delay notice
460
+ if ( $delay > 0 ) {
461
+ $activation = array_merge( $activation, array( 'update_delay_date' => time() + $delay ) );
462
+ // hide notice permanently
463
+ } else {
464
+ $activation = array_merge( $activation, array( 'update_delay_date' => 0, 'update_notice' => false ) );
465
+ }
466
+
467
+ // update activation options
468
+ $result = update_option( 'iubenda_activation_data', $activation );
469
+ }
470
+
471
+ echo json_encode( $result );
472
+ exit;
473
+ }
474
+
475
+ /**
476
+ * Plugin options migration for versions < 1.14.0
477
+ *
478
+ * @return void
479
+ */
480
+ public function update_plugin() {
481
+ if ( ! current_user_can( 'install_plugins' ) )
482
+ return;
483
+
484
+ $db_version = get_option( 'iubenda_cookie_law_version' );
485
+ $db_version = ! $db_version ? '1.13.0' : $db_version;
486
+
487
+ if ( $db_version != false ) {
488
+ if ( version_compare( $db_version, '1.14.0', '<' ) ) {
489
+ $options = array();
490
+
491
+ $old_new = array(
492
+ 'iubenda_parse' => 'parse',
493
+ 'skip_parsing' => 'skip_parsing',
494
+ 'iubenda_ctype' => 'ctype',
495
+ 'iubenda_parse' => 'parse',
496
+ 'parser_engine' => 'parser_engine',
497
+ 'iubenda_output_feed' => 'output_feed',
498
+ 'iubenda-code-default' => 'code_default',
499
+ 'default_skip_parsing' => '',
500
+ 'default_iubendactype' => '',
501
+ 'default_iubendaparse' => '',
502
+ 'default_parser_engine' => '',
503
+ 'iub_code' => '',
504
+ );
505
+
506
+ foreach ( $old_new as $old => $new ) {
507
+ if ( $new ) {
508
+ $options[$new] = get_option( $old );
509
+ }
510
+ delete_option( $old );
511
+ }
512
+
513
+ // multilang support
514
+ if ( ! empty( iubenda()->languages ) ) {
515
+ foreach ( iubenda()->languages as $lang_id => $lang_name ) {
516
+ $code = get_option( 'iubenda-code-' . $lang_id );
517
+
518
+ if ( ! empty( $code ) ) {
519
+ $options['code_' . $lang_id] = $code;
520
+
521
+ delete_option( 'iubenda-code-' . $lang_id );
522
+ }
523
+ }
524
+ }
525
+
526
+ add_option( 'iubenda_cookie_law_solution', $options, '', 'no' );
527
+ add_option( 'iubenda_cookie_law_version', iubenda()->version, '', 'no' );
528
+ }
529
+ }
530
+ }
531
+
532
+ /**
533
+ * Load admin options page.
534
+ *
535
+ * @return void
536
+ */
537
+ public function options_page() {
538
+ global $pagenow;
539
+
540
+ if ( ! current_user_can( apply_filters( 'iubenda_cookie_law_cap', 'manage_options' ) ) ) {
541
+ wp_die( __( "You don't have permission to access this page.", 'iubenda' ) );
542
+ }
543
+
544
+ $tab_key = ! empty( $_GET['tab'] ) ? esc_attr( $_GET['tab'] ) : 'cs';
545
+
546
+ // get redirect url
547
+ if ( iubenda()->options['cs']['menu_position'] === 'submenu' && $pagenow === 'admin.php' ) {
548
+ // sub menu
549
+ $redirect_to = admin_url( 'options-general.php?page=iubenda&tab=' . $tab_key );
550
+ } else {
551
+ // top menu
552
+ $redirect_to = admin_url( 'admin.php?page=iubenda&tab=' . $tab_key );
553
+ }
554
+ ?>
555
+ <div class="wrap">
556
+
557
+ <div id="iubenda-header">
558
+ <?php
559
+ echo '
560
+ <a class="iubenda-link" href="http://iubenda.com" title="iubenda" title="_blank">
561
+ <img id="iubenda-logo" alt="iubenda logo" width="300" height="90" src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgNjM3LjggMjgzLjUiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDYzNy44IDI4My41OyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHN0eWxlIHR5cGU9InRleHQvY3NzIj4uc3Qwe2ZpbGw6IzFDQzY5MTt9LnN0MXtmaWxsOiM1MTUyNTQ7fTwvc3R5bGU+PHBhdGggY2xhc3M9InN0MCIgZD0iTTE3OC45LDk5LjljMCw4LjItMywxNS42LTgsMjEuNGw3LjIsOTUuNGgtNjQuMmw3LTkzLjhjLTUuOS02LTkuNi0xNC4xLTkuNi0yMy4xYzAtMTguMywxNS4xLTMzLjEsMzMuOC0zMy4xUzE3OC45LDgxLjYsMTc4LjksOTkuOSBNMTQ1LjEsMTA3LjRjNC41LDAsOC4xLTMuNiw4LjEtOC4xcy0zLjYtOC04LjEtOGMtNC41LDAtOC4xLDMuNi04LjEsOFMxNDAuNiwxMDcuNCwxNDUuMSwxMDcuNCBNMTUxLjUsMTM2LjJsLTExLjEsMTEuMXY0My4xaDExLjFWMTM2LjJ6Ii8+PHBhdGggY2xhc3M9InN0MSIgZD0iTTI2NS40LDE3OC42Yy0yLjMsMS4yLTQuNywxLjgtNy4yLDEuOGMtMi44LDAtNS4zLTAuOC03LjQtMi40Yy0yLjEtMS42LTMuNS0zLjctNC4zLTYuMmMtMC44LTIuNS0xLjItNi4xLTEuMi0xMC44di0xOC4yYzAsMCwwLTAuOSwwLTIuOGMwLTAuNSwwLTIuOC0xLjUtMy41Yy0wLjItMC4xLTAuNi0wLjItMS4yLTAuM2MtMC40LDAtMC44LTAuNC0wLjgtMC44bDAtMi40YzAtMC41LDAuNC0wLjksMC44LTAuOWg5LjNjMS4zLDAsMi40LDEuMSwyLjQsMi40VjE0N2wwLDE1LjVjMCw0LjYsMC44LDcuNywyLjUsOS4xYzEuNiwxLjUsMy42LDIuMiw1LjksMi4yYzEuNiwwLDMuNC0wLjUsNS40LTEuNWMyLTEsNS4zLTIuOCw4LjEtNS42bDAtMi40bDAtMjIuMlYxNDBjMC0wLjUsMC0yLjgtMS40LTMuNWMtMC4yLTAuMS0wLjYtMC4yLTEuMS0wLjNjLTAuNC0wLjEtMC44LTAuNC0wLjgtMC44bDAtMi40YzAtMC41LDAuNC0wLjksMC45LTAuOWg5LjJjMS4zLDAsMi40LDEuMSwyLjQsMi40djhjMCwwLjEsMCwwLjEsMCwwLjJ2MTYuNmMwLDMuOCwwLDcuNCwwLDEwLjZjMCwwLjcsMCwxLjIsMCwxLjJjMCwwLjUtMC4xLDMuMSwxLjQsMy44YzAuMiwwLjEsMC42LDAuMiwxLjIsMC4zYzAuNCwwLDAuOCwwLjQsMC44LDAuOGwwLDIuNGMwLDAuNS0wLjQsMC44LTAuOSwwLjloLTkuMmMtMS4zLDAtMi40LTEuMS0yLjQtMi40bDAtNC41bDAtMi41QzI3MS45LDE3NC41LDI2Ny43LDE3Ny40LDI2NS40LDE3OC42Ii8+PHBhdGggY2xhc3M9InN0MSIgZD0iTTMwOS4yLDE3NmMxLjksMC45LDMuOSwxLjMsNiwxLjNjMy4yLDAsNi4zLTEuNyw5LTUuMmMyLjgtMy41LDQuMi04LjUsNC4yLTE1LjJjMC02LjEtMS40LTEwLjgtNC4yLTE0LjFjLTIuOC0zLjMtNi00LjktOS41LTQuOWMtMS45LDAtMy44LDAuNS01LjcsMS40Yy0xLjIsMC42LTIuOCwxLjgtNC43LDMuNGMtMC41LDAuNS0wLjgsMS4xLTAuOCwxLjhWMTcxYzAsMC43LDAuMywxLjQsMC44LDEuOEMzMDYsMTc0LjIsMzA3LjYsMTc1LjMsMzA5LjIsMTc2IE0yOTQuOCwxMThjMC0wLjUsMC0yLjctMS40LTMuNGMtMC4yLTAuMS0wLjMtMC4xLTAuNi0wLjJjLTAuNC0wLjEtMC42LTAuNC0wLjYtMC44bDAtMi4zYzAtMC41LDAuNC0wLjgsMC45LTAuOWgxLjhoNi41YzEuMywwLDIuMywxLDIuMywyLjNsMCwxMnYxNS40YzQuNy02LjQsOS44LTkuNiwxNS4zLTkuNmM1LDAsOS40LDIuMSwxMy4xLDYuM2MzLjcsNC4yLDUuNiw5LjksNS42LDE3LjJjMCw4LjUtMi45LDE1LjMtOC42LDIwLjVjLTQuOSw0LjQtMTAuNSw2LjctMTYuNSw2LjdjLTIuOCwwLTUuNy0wLjUtOC43LTEuNWMtMi41LTAuOS01LjEtMi4xLTcuNy0zLjdjLTAuOC0wLjUtMS4zLTEuNC0xLjMtMi40di00NmMwLTAuOSwwLTIsMC0zLjNMMjk0LjgsMTE4eiIvPjxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik0zODkuMywxNzkuMWMtMC41LDAtMC45LTAuNC0wLjktMC45bDAtMi4zYzAtMC40LDAuMy0wLjgsMC43LTAuOGMwLjUtMC4xLDAuOC0wLjEsMS0wLjJjMS40LTAuNywxLjQtMi45LDEuNC0zLjR2LTIuN2MwLDAsMC01LjgsMC0xNy41YzAtMS45LDAtMy44LDAuMS01LjVsMC00LjZjMC0wLjUsMC0xLDAtMS41YzAtMC42LDAtMi44LTEuNC0zLjVjLTAuMS0wLjEtMC4zLTAuMS0wLjUtMC4yYy0wLjQtMC4xLTAuNi0wLjQtMC42LTAuOGwwLTIuM2MwLTAuNSwwLjQtMC44LDAuOS0wLjloOC4xYzEuMywwLDIuMywxLDIuMywyLjN2My40YzAsMCwwLDAuNiwwLDEuOGMwLDAuMywwLjIsMC42LDAuNiwwLjZjMC4yLDAsMC4zLTAuMSwwLjQtMC4yYzUuNC01LjksMTIuMy04LjgsMTcuMi04LjhjMi43LDAsNSwwLjYsNi45LDEuOWMxLjksMS4zLDMuNCwzLjQsNC42LDYuM2MwLjgsMi4xLDEuMiw1LjIsMS4yLDkuNHYxNi41bDAsNi4zYzAsMC41LDAsMi43LDEuNCwzLjRjMC4yLDAuMSwwLjQsMC4yLDAuOCwwLjJjMC40LDAuMSwwLjcsMC40LDAuNywwLjhsMCwyLjNjMCwwLjUtMC40LDAuOC0wLjgsMC45Yy0wLjgsMC0xLjUsMC0yLDBoLTYuNWMtMC4xLDAtMC4zLDAtMC40LDBoLTMuMWMtMS4xLDAtMi0wLjktMi0yYzAtMSwwLjctMS45LDEuNi0yLjJjMC4xLDAsMC4xLDAsMC4yLTAuMWMxLTAuNSwxLjMtMS44LDEuNC0yLjd2LTcuNGwwLTE1LjJjMC00LjMtMC42LTcuNC0xLjctOS4zYy0xLjItMS45LTMuMS0yLjktNS44LTIuOWMtNC4yLDAtMTAuMywyLjItMTQuNCw2Ljd2MjAuOHYwLjNsMCw2LjRjMCwwLjUsMCwyLjgsMS40LDMuNWMwLjEsMCwwLjEsMCwwLjIsMC4xYzEsMC4zLDEuNiwxLjIsMS42LDIuMmMwLDEuMS0wLjksMi0yLDJIMzk0QzM5NCwxNzkuMSwzOTIuNCwxNzkuMSwzODkuMywxNzkuMSIvPjxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik01MTUsMTUzLjRjLTYuNiwxLjMtMTAuNCwyLjItMTEuNCwyLjVjLTMuNywxLjItNi42LDIuNi02LjgsOC43Yy0wLjEsMi41LDAuOCw0LjcsMi4zLDYuM2MxLjUsMS43LDMuMywyLjUsNS4zLDIuNWMyLjUsMCw1LjctMS44LDkuNi00LjhjMC43LTAuNSwxLjEtMS4zLDEuMS0yLjJWMTUzLjR6IE01MjMuOCwxNzAuOGMwLDAuMSwwLDAuMiwwLDAuMmMwLDAuMiwwLDAuMywwLDAuNGMwLjEsMS40LDAuNiwyLjQsMS40LDIuOGMwLjIsMC4xLDAuNCwwLjIsMC42LDAuMmMwLjQsMC4xLDAuNywwLjQsMC43LDAuOGwwLDIuNGMwLDAuNS0wLjQsMC44LTAuOSwwLjloLTguM2MtMS4zLDAtMi4zLTEtMi4zLTIuM3YtNC41Yy01LDMuOS04LjIsNi4xLTkuNSw2LjdjLTEuOSwwLjktNCwxLjMtNi4xLDEuM2MtMy40LDAtNi4yLTEuMi04LjQtMy40Yy0yLjItMi4zLTMuMy01LjMtMy4zLTkuMWMwLTIuNCwwLjUtNC40LDEuNi02LjJjMS41LTIuNCwzLjctNS4yLDcuNi02LjhjNC0xLjYsNy4zLTIsMTgtNC40YzAtMC4zLDAtNCwwLTQuM2MwLTQuNS0wLjgtOS4yLTguNC04LjdjLTUuMywwLjMtMTAuMiwyLTE0LjcsNWMtMC40LDAuMy0wLjksMC4yLTEuMi0wLjJjLTAuMS0wLjEtMC4xLTAuMy0wLjEtMC41di0yLjhjMC0xLjUsMC4zLTIuNCwwLjktMi45YzMuMS0yLjUsMTAuOS01LjUsMTguNS01YzguNCwwLjYsMTEuNCw0LDEyLjksOS4zYzAuNSwxLjYsMSwyLjgsMSw3LjV2MTQuNWMwLDIsMCw0LDAsNS44VjE3MC44eiIvPjxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik00NjUuNCwxMzcuOGMtMS43LTEtMy40LTEuNS01LTEuNWMtMywwLTUuOCwxLjMtOC4zLDMuOGMtMi43LDIuOC00LjYsNi41LTQuNiwxMy41YzAsNywxLjUsMTIuNCw0LjYsMTYuMmMzLDMuNyw2LjQsNS42LDEwLjIsNS42YzIuNywwLDUuMy0xLjEsNy44LTMuNGMwLjktMC44LDEuNC0xLjksMS40LTN2LTIwLjhDNDcxLjQsMTQzLjksNDY5LjEsMTQwLDQ2NS40LDEzNy44IE00ODEuMywxNzQuNmMwLjEsMC4xLDAuMywwLjEsMC41LDAuMmMwLjQsMC4xLDAuNiwwLjQsMC42LDAuOGwwLDIuM2MwLDAuNS0wLjQsMC44LTAuOSwwLjloLThjLTEuMiwwLTIuMy0xLTIuMy0yLjJ2LTIuMmMtMi4zLDIuNC00LjYsNC4yLTYuOCw1LjNjLTIuMiwxLjEtNC42LDEuNi03LjEsMS42Yy01LjIsMC05LjctMi4yLTEzLjYtNi42Yy0zLjktNC40LTUuOC0xMC01LjgtMTYuOXMyLjEtMTMuMSw2LjQtMTguOGM0LjMtNS43LDkuOC04LjUsMTYuNS04LjVjNC4yLDAsNy42LDEuMywxMC40LDR2LTE2LjdjMC0wLjUsMC0yLjctMS40LTMuNGMtMC4xLTAuMS0wLjMtMC4xLTAuNS0wLjJjLTAuNC0wLjEtMC42LTAuNC0wLjYtMC44bDAtMi40YzAtMC41LDAuNC0wLjksMC45LTAuOWg3LjljMS4yLDAsMi4zLDEsMi4zLDIuMnY1OC45QzQ3OS45LDE3MS44LDQ3OS45LDE3My45LDQ4MS4zLDE3NC42Ii8+PHBhdGggY2xhc3M9InN0MSIgZD0iTTM1MCwxNTAuMmMwLDAuMSwwLDAuMywwLjEsMC4zYzAuMSwwLjEsMC4yLDAuMSwwLjQsMC4xaDIzLjljMC4zLDAsMC41LTAuMiwwLjUtMC40YzAuMy0yLjUsMC40LTctMy4zLTEwLjhjLTEuOC0xLjktNC4xLTIuOC04LjMtMi44QzM1NS43LDEzNi42LDM1MC44LDE0My45LDM1MCwxNTAuMiBNMzQ3LjUsMTc0LjljLTMuOS00LjMtNS45LTExLjMtNS45LTE4LjJjMC03LjMsMi4zLTEzLjksNi40LTE4LjdjNC4zLTUsMTAuMi03LjcsMTcuMS03LjdjNS44LDAsMTAuMiwyLDEzLjIsNS44YzIuNywzLjYsNC4xLDguOCw0LjEsMTUuNGMwLDAuOCwwLDEuOS0wLjEsMy4zYy0wLjEsMC45LTAuOCwxLjYtMS43LDEuNmgtMjkuOGMtMC4xLDAtMC4zLDAuMS0wLjQsMC4xYy0wLjEsMC4xLTAuMSwwLjItMC4xLDAuNGMwLjEsNS40LDEuOCwxMCw1LDEzLjJjMy4xLDMuMiw3LjQsNC45LDEyLjQsNC45YzMuNywwLDguNi0xLDEyLjQtMi4xYzAuNS0wLjIsMS4xLDAuMSwxLjMsMC43YzAuMSwwLjIsMC4xLDAuNCwwLDAuNWwtMC41LDEuOWMtMC4yLDAuNy0wLjcsMS4zLTEuMywxLjZjLTMuNywxLjgtOS4zLDMuNS0xNSwzLjVDMzU3LjYsMTgxLjIsMzUxLjYsMTc5LjUsMzQ3LjUsMTc0LjkiLz48cGF0aCBjbGFzcz0ic3QxIiBkPSJNMjMxLjEsMTM1Ljl2MzYuOWMwLDEsMC42LDEuOSwxLjQsMi4zYzAuOSwwLjQsMS40LDEuMywxLjQsMi4zdjAuN2MwLDAuOC0wLjYsMS40LTEuNCwxLjRIMjIwYy0wLjgsMC0xLjQtMC42LTEuNC0xLjR2LTAuN2MwLTEsMC42LTEuOSwxLjQtMi4zYzAuOS0wLjQsMS40LTEuMywxLjQtMi4zdi0zNS43YzAtMC41LTAuNC0wLjktMC45LTAuOXMtMC45LTAuNC0wLjktMC45di0xLjJjMC0xLjIsMC45LTIuMSwyLjEtMi4xaDUuNkMyMjkuNCwxMzIsMjMxLjEsMTMzLjcsMjMxLjEsMTM1LjkiLz48cGF0aCBjbGFzcz0ic3QxIiBkPSJNMjI2LjMsMTEwLjhjMy4zLDAsNiwyLjcsNiw1LjljMCwzLjMtMi43LDUuOS02LDUuOXMtNi0yLjctNi01LjlDMjIwLjMsMTEzLjUsMjIzLDExMC44LDIyNi4zLDExMC44Ii8+PC9zdmc+"/>
562
+ </a>';
563
+
564
+ if ( $tab_key === 'cs' ) {
565
+ echo '
566
+ <p class="iubenda-text">
567
+ ' . __( "This plugin is the easiest and most comprehensive way to adapt your WordPress site to the ePrivacy (EU Cookie Law). Upon your users' first visit, the plugin will take care of collecting their consent, blocking the most popular cookie-scripts and subsequently reactivating these scripts as soon as consent is provided. The basic settings include obtaining consent by a simple scroll action (the most effective method) and script reactivation without refreshing the page (asynchronous script reactivation).", 'iubenda' ) . '
568
+ </p>
569
+ <p class="iubenda-text">
570
+ <span class="iubenda-title">' . __( "Does the Cookie Solution support IAB's Transparency and Consent Framework?", 'iubenda' ) . '</span><br />
571
+ ' . sprintf( __( "Yes it does. You can read more about it <a href=\"%s\" class=\"iubenda-url\" target=\"_blank\">here.</a>", 'iubenda' ), $this->links['iab'] ) . '
572
+ </p>
573
+ <p class="iubenda-text">
574
+ <span class="iubenda-title">' . __( "Would you like to know more about the cookie law?", 'iubenda' ) . '</span><br />
575
+ ' . sprintf( __( "Read our <a href=\"%s\" class=\"iubenda-url\" target=\"_blank\">complete guide to the cookie law.</a>", 'iubenda' ), $this->links['guide'] ) . '
576
+ </p>
577
+ <p class="iubenda-text">
578
+ <span class="iubenda-title">' . __( "What is the full functionality of the plugin?", 'iubenda' ) . '</span><br />
579
+ ' . sprintf( __( "Visit our <a href=\"%s\" class=\"iubenda-url\" target=\"_blank\">plugin page.</a>", 'iubenda' ), $this->links['plugin_page'] ) . '
580
+ </p>
581
+ <p class="iubenda-text">
582
+ <span class="iubenda-title">' . __( "Enter the iubenda code for the Cookie Solution below.", 'iubenda' ) . '</span><br />
583
+ ' . sprintf( __( "In order to run the plugin, you need to enter the iubenda code that activates the cookie law banner and the cookie policy in the form below. This code can be generated on www.iubenda.com, following <a href=\"%s\" class=\"iubenda-url\" target=\"_blank\">this guide.</a>", 'iubenda' ), $this->links['generating_code'] ) . '
584
+ </p>';
585
+ } else {
586
+ echo '
587
+ <p class="iubenda-text">
588
+ ' . __( 'Maintaining comprehensive records of consent is a vital part of privacy compliance in general but is specifically required under the GDPR. These records should include a way of identifying the user, store proof of consent, record of the consenting action, and the legal documents available to the user at the time of consent, among other things. You can read about the <a href="https://www.iubenda.com/en/help/5428-gdpr-guide#records-of-consent" target="_blank">full requirements here</a>.', 'iubenda' ) . '
589
+ </p>';
590
+ }
591
+ ?>
592
+ </div>
593
+
594
+ <?php
595
+ if ( $tab_key === 'cs' ) {
596
+ // add per-purpose notice
597
+ if ( iubenda()->options['cs']['skip_parsing'] ) {
598
+ $iubenda_code = '';
599
+
600
+ if ( iubenda()->multilang === true && defined( 'ICL_LANGUAGE_CODE' ) && isset( iubenda()->options['cs']['code_' . ICL_LANGUAGE_CODE] ) ) {
601
+ $iubenda_code = iubenda()->options['cs']['code_' . ICL_LANGUAGE_CODE];
602
+
603
+ // no code for current language, use default
604
+ if ( ! $iubenda_code )
605
+ $iubenda_code = iubenda()->options['cs']['code_default'];
606
+ } else
607
+ $iubenda_code = iubenda()->options['cs']['code_default'];
608
+
609
+ $per_purpose_enabled = preg_match( '/(?:"|\')perPurposeConsent(?:"|\')\: *(?:"|\'*)true(?:"|\'*)/', $iubenda_code );
610
+ $reject_enabled = preg_match( '/(?:"|\')rejectButtonDisplay(?:"|\')\: *(?:"|\'*)true(?:"|\'*)/', $iubenda_code );
611
+
612
+ if ( $per_purpose_enabled || $reject_enabled )
613
+ $this->add_notice( 'iub_per_purpose_enabled', sprintf( __( 'If you are using per-purpose script blocking or Reject option please disable the "Leave scripts untouched on the page if the user has already given consent" option. <a href="%s" target="_self">Disable now</a>', 'iubenda' ), esc_url( add_query_arg( 'action', 'disable_skip_parsing', $redirect_to ) ) ), 'notice' );
614
+ }
615
+
616
+ // add AMP notice
617
+ if ( iubenda()->options['cs']['amp_support'] && iubenda()->options['cs']['amp_template_done'] ) {
618
+ $ssl_support = true;
619
+
620
+ // multilang support
621
+ if ( iubenda()->multilang && ! empty( iubenda()->languages ) ) {
622
+ foreach ( iubenda()->languages as $lang_id => $lang_name ) {
623
+ $url = iubenda()->options['cs']['amp_source'] === 'remote' ? iubenda()->options['cs']['amp_template'][$lang_id] : iubenda()->AMP->get_amp_template_url( $lang_id );
624
+ $bits = explode( '/', $url );
625
+
626
+ if ( $bits[0] === 'http:' )
627
+ $ssl_support = false;
628
+ }
629
+ } else {
630
+ $url = iubenda()->options['cs']['amp_source'] === 'remote' ? iubenda()->options['cs']['amp_template'] : iubenda()->AMP->get_amp_template_url();
631
+ $bits = explode( '/', $url );
632
+
633
+ if ( $bits[0] === 'http:' )
634
+ $ssl_support = false;
635
+ }
636
+
637
+ if ( ! $ssl_support )
638
+ $this->add_notice( 'iub_amp_ssl_required', __( 'AMP configuration file requires HTTPS. Make sure your SSL Certificate is configured correctly.', 'iubenda' ), 'error' );
639
+ }
640
+
641
+ }
642
+
643
+ // render custom notices
644
+ $this->print_notices();
645
+ ?>
646
+
647
+ <h2 style="display: none;"></h2>
648
+ <h2 class="nav-tab-wrapper iubenda-tab-wrapper">
649
+ <a class="nav-tab<?php echo $tab_key == 'cs' ? ' nav-tab-active' : ''; ?>" href="<?php echo esc_url( iubenda()->base_url ); ?>"><?php _e( 'Cookie Solution', 'iubenda' ); ?></a>
650
+ <a class="nav-tab<?php echo $tab_key == 'cons' ? ' nav-tab-active' : ''; ?>" href="<?php echo esc_url( add_query_arg( array( 'tab' => 'cons' ), iubenda()->base_url ) ); ?>"><?php _e( 'Consent Solution', 'iubenda' ); ?></a>
651
+ </h2>
652
+
653
+ <div id="iubenda-settings">
654
+
655
+ <form id="iubenda-tabs" action="options.php" method="post">
656
+
657
+
658
+ <?php
659
+ if ( $tab_key === 'cs' ) {
660
+ echo '<p>' . sprintf( __( 'This plugin drastically reduces the need for direct interventions in the code of the site by integrating with iubenda\'s Cookie Solution. It provides a fully customizable cookie banner, dynamically generates a cookie policy <a href="%s" target="_blank">to match the services in use on your site</a>, and, fully manages cookie-related consent - including the blocking of the most common widgets and third-party cookies before consent is received - in order to comply with the GDPR and ePrivacy.', 'iubenda' ), 'https://www.iubenda.com/en/help/19004-how-to-use-the-site-scanner-from-within-the-generator' ) . '</p>';
661
+ } else {
662
+ echo '<p>' . __( 'Maintaining valid records of consent is a vital part of privacy compliance in general, and it is specifically required under the GDPR. These records should include a userid, timestamp, consent proof, record of the consenting action, and the legal documents available to the user at the time of consent, among other things. This plugin is THE most complete solution for recording, sorting and maintaining GDPR records of consent*. The plugin also boasts built-in compatibility with WordPress comment form, Contact Form 7 and WP Forms plugins for your convenience, but can be manually integrated with any type of web-form and can even store consent proofs for consents collected offline (e.g in-store sign-ups) via WP media upload.' ) . '</p>';
663
+ }
664
+ ?>
665
+
666
+ <?php
667
+ settings_fields( $this->tabs[$tab_key]['key'] );
668
+ do_settings_sections( $this->tabs[$tab_key]['key'] );
669
+
670
+ if ( ! in_array( $this->action, array( 'save', 'edit' ) ) ) {
671
+ echo ' <p class="submit submit-' . $tab_key . '">';
672
+
673
+ // consent solution tab only
674
+ if ( $tab_key != 'cs' && ! empty( iubenda()->options['cons']['public_api_key'] ) ) {
675
+ echo '<a href="' . esc_url( add_query_arg( array( 'tab' => 'cons', 'action' => 'autodetect' ), iubenda()->base_url ) ) . '" class="button button-primary button-large iub-autodetect-forms">' . esc_html__( 'Autodetect Forms', 'iubenda' ) . '</a>';
676
+ echo '<br />';
677
+ }
678
+ submit_button( '', 'primary', $this->tabs[$tab_key]['submit'], false );
679
+ echo ' ';
680
+ submit_button( __( 'Reset to defaults', 'iubenda' ), 'secondary', $this->tabs[$tab_key]['reset'], false );
681
+ echo ' </p>';
682
+ }
683
+ ?>
684
+
685
+ </form>
686
+
687
+ </div>
688
+
689
+ <div id="iubenda-footer">
690
+ <?php echo '
691
+ <p class="iubenda-text">
692
+ <span class="iubenda-title">' . __( 'Need support for this plugin?', 'iubenda' ) . '</span><br />
693
+ ' . sprintf( __( "Visit our <a href=\"%s\" class=\"iubenda-url\" target=\"_blank\">support forum.</a>", 'iubenda' ), $this->links['support_forum'] ) . '
694
+ </p>';
695
+ ?>
696
+ </div>
697
+
698
+ <div class="clear"></div>
699
+ </div>
700
+ <?php
701
+ }
702
+
703
+ /**
704
+ * Code option.
705
+ *
706
+ * @return mixed
707
+ */
708
+ public function iub_code() {
709
+ // multilang support
710
+ if ( iubenda()->multilang && ! empty( iubenda()->languages ) ) {
711
+ echo '
712
+ <div id="contextual-help-wrap" class="contextual-help-wrap hidden" tabindex="-1" style="display: block;">
713
+ <div id="contextual-help-back" class="contextual-help-back"></div>
714
+ <div id="contextual-help-columns" class="contextual-help-columns">
715
+ <div class="contextual-help-tabs">
716
+ <ul>';
717
+ foreach ( iubenda()->languages as $lang_id => $lang_name ) {
718
+ echo '
719
+ <li class="' . ( iubenda()->lang_default == $lang_id ? 'active' : '' ) . '">
720
+ <a href="#tab-panel-' . $lang_id . '" aria-controls="tab-panel-' . $lang_id . '">' . $lang_name . '</a>
721
+ </li>';
722
+ }
723
+ echo '
724
+ </ul>
725
+ </div>
726
+
727
+ <div id="contextual-help-tabs-wrap" class="contextual-help-tabs-wrap">';
728
+ foreach ( iubenda()->languages as $lang_id => $lang_name ) {
729
+ // get code for the language
730
+ $code = ! empty( iubenda()->options['cs']['code_' . $lang_id] ) ? html_entity_decode( iubenda()->parse_code( iubenda()->options['cs']['code_' . $lang_id] ) ) : '';
731
+ // handle default, if empty
732
+ $code = empty( $code ) && $lang_id == iubenda()->lang_default ? html_entity_decode( iubenda()->parse_code( iubenda()->options['cs']['code_default'] ) ) : $code;
733
+
734
+ echo '
735
+ <div id="tab-panel-' . $lang_id . '" class="help-tab-content' . ( iubenda()->lang_default == $lang_id ? ' active' : '' ) . '">
736
+ <textarea name="iubenda_cookie_law_solution[code_' . $lang_id . ']" class="large-text" cols="50" rows="10">' . $code . '</textarea>
737
+ <p class="description">' . sprintf( __( 'Enter the iubenda code for %s.', 'iubenda' ), $lang_name ) . '</p>
738
+ </div>';
739
+ }
740
+ echo '
741
+ </div>
742
+ </div>
743
+ </div>';
744
+ } else {
745
+ echo '
746
+ <div id="iub_code_default">
747
+ <textarea name="iubenda_cookie_law_solution[code_default]" class="large-text" cols="50" rows="10">' . html_entity_decode( iubenda()->parse_code( iubenda()->options['cs']['code_default'] ) ) . '</textarea>
748
+ <p class="description">' . __( 'Enter the iubenda code.', 'iubenda' ) . '</p>
749
+ </div>';
750
+ }
751
+ }
752
+
753
+ /**
754
+ * Custom scripts option.
755
+ *
756
+ * @return void
757
+ */
758
+ public function iub_custom_scripts() {
759
+ echo '
760
+ <div id="contextual-help-wrap-2" class="contextual-help-wrap hidden" tabindex="-1" style="display: block;">
761
+ <div id="contextual-help-back-2" class="contextual-help-back"></div>
762
+ <div id="contextual-help-columns-2" class="contextual-help-columns">
763
+ <div class="contextual-help-tabs">
764
+ <ul>
765
+ <li class="active">
766
+ <a href="#tab-panel-scripts" aria-controls="tab-panel-scripts">' . esc_html__( 'Scripts', 'iubenda' ) . '</a>
767
+ </li>
768
+ <li>
769
+ <a href="#tab-panel-iframes" aria-controls="tab-panel-iframes">' . esc_html__( 'Iframes', 'iubenda' ) . '</a>
770
+ </li>
771
+ </ul>
772
+ </div>
773
+ <div id="contextual-help-tabs-wrap-2" class="contextual-help-tabs-wrap">
774
+ <div id="tab-panel-scripts" class="help-tab-content active">
775
+ <p class="description">' . __( 'Provide a list of custom scripts you\'d like to block and assign their purpose.', 'iubenda' ) . '</p>
776
+ <div id="custom-script-field-template" class="template-field" style="display: none;">
777
+ <input type="text" class="regular-text" value="" name="iubenda_cookie_law_solution[custom_scripts][script][]" placeholder="' . __( 'Enter custom script', 'iubenda' ) . '" /> ' . $this->render_tag_types( 'script', 0 ) . ' <a href="#" class="remove-custom-script-field button-secondary" title="' . __( 'Remove', 'iubenda' ) . '">-</a>
778
+ </div>';
779
+
780
+ if ( ! empty( iubenda()->options['cs']['custom_scripts'] ) ) {
781
+ foreach ( iubenda()->options['cs']['custom_scripts'] as $script => $type ) {
782
+ echo '
783
+ <div class="custom-script-field">
784
+ <input type="text" class="regular-text" value="' . esc_attr( $script ) . '" name="iubenda_cookie_law_solution[custom_scripts][script][]" placeholder="' . __( 'Enter custom script', 'iubenda' ) . '" /> ' . $this->render_tag_types( 'script', $type ) . ' <a href="#" class="remove-custom-script-field button-secondary" title="' . __( 'Remove', 'iubenda' ) . '">-</a>
785
+ </div>';
786
+ }
787
+ }
788
+
789
+ echo '
790
+ <a href="#" class="add-custom-script-field button-secondary">Add New Script</a>
791
+ </div>
792
+ <div id="tab-panel-iframes" class="help-tab-content">
793
+ <p class="description">' . __( 'Provide a list of custom iframes you\'d like to block and assign their purpose. ', 'iubenda' ) . '</p>
794
+ <div id="custom-iframe-field-template" class="template-field" style="display: none;">
795
+ <input type="text" class="regular-text" value="" name="iubenda_cookie_law_solution[custom_iframes][iframe][]" placeholder="' . __( 'Enter custom iframe', 'iubenda' ) . '" /> ' . $this->render_tag_types( 'iframe', 0 ) . ' <a href="#" class="remove-custom-iframe-field button-secondary" title="' . __( 'Remove', 'iubenda' ) . '">-</a>
796
+ </div>';
797
+
798
+ if ( ! empty( iubenda()->options['cs']['custom_iframes'] ) ) {
799
+ foreach ( iubenda()->options['cs']['custom_iframes'] as $iframe => $type ) {
800
+ echo '
801
+ <div class="custom-iframe-field">
802
+ <input type="text" class="regular-text" value="' . esc_attr( $iframe ) . '" name="iubenda_cookie_law_solution[custom_iframes][iframe][]" placeholder="' . __( 'Enter custom iframe', 'iubenda' ) . '" /> ' . $this->render_tag_types( 'iframe', $type ) . ' <a href="#" class="remove-custom-iframe-field button-secondary" title="' . __( 'Remove', 'iubenda' ) . '">-</a>
803
+ </div>';
804
+ }
805
+ }
806
+
807
+ echo '
808
+ <a href="#" class="add-custom-iframe-field button-secondary">Add New Iframe</a>
809
+ </div>
810
+ </div>
811
+ </div>
812
+ </div>';
813
+ }
814
+
815
+ /**
816
+ * Prepare tag types select.
817
+ *
818
+ * @param string $type
819
+ * @param int $selected
820
+ * @return string
821
+ */
822
+ function render_tag_types( $type, $selected ) {
823
+ $html = '<select name="iubenda_cookie_law_solution[custom_' . $type . 's][type][]">';
824
+
825
+ foreach ( $this->tag_types as $tag_id => $tag_name ) {
826
+ $html .= '<option value="' . esc_attr( $tag_id ) . '" ' . selected( $selected, $tag_id, false ) . '>' . esc_html( $tag_name ) . '</option>';
827
+ }
828
+
829
+ return $html . '</select>';
830
+ }
831
+
832
+ /**
833
+ * Parsing option.
834
+ *
835
+ * @return mixed
836
+ */
837
+ public function iub_parse() {
838
+ echo '
839
+ <div id="iub_parse_container">
840
+ <label><input id="iub_parse" type="checkbox" name="iubenda_cookie_law_solution[parse]" value="1" ' . checked( true, (bool) iubenda()->options['cs']['parse'], false ) . '/>' . __( 'Automatically block scripts detected by the plugin', 'iubenda' ) . '</label>
841
+ <p class="description">' . '(' . sprintf( __( "see <a href=\"%s\" target=\"_blank\">our documentation</a> for the list of detected scripts.", 'iubenda' ), $this->links['documentation'] ) . ')' . '</p>
842
+ <div id="iub_parser_engine_container"' . ( iubenda()->options['cs']['parse'] === false ? ' style="display: none;"' : '' ) . '>
843
+ <div>
844
+ <label><input id="iub_parser_engine-new" type="radio" name="iubenda_cookie_law_solution[parser_engine]" value="new" ' . checked( 'new', iubenda()->options['cs']['parser_engine'], false ) . ' />' . __( 'Primary', 'iubenda' ) . '</label>
845
+ <label><input id="iub_parser_engine-default" type="radio" name="iubenda_cookie_law_solution[parser_engine]" value="default" ' . checked( 'default', iubenda()->options['cs']['parser_engine'], false ) . ' />' . __( 'Secondary', 'iubenda' ) . '</label>
846
+ <p class="description">' . __( 'Select parsing engine.', 'iubenda' ) . '</p>
847
+ </div>
848
+ <div>
849
+ <label><input id="iub_skip_parsing" type="checkbox" name="iubenda_cookie_law_solution[skip_parsing]" value="1" ' . checked( true, (bool) iubenda()->options['cs']['skip_parsing'], false ) . '/>' . __( 'Leave scripts untouched on the page if the user has already given consent', 'iubenda' ) . '</label>
850
+ <p class="description">(' . __( "improves performance, highly recommended, to be deactivated only if your site uses a caching system or if you're collecting per-category consent.", 'iubenda' ) . ')</p>
851
+ </div>
852
+ </div>
853
+ </div>';
854
+ }
855
+
856
+ /**
857
+ * Ctype option.
858
+ *
859
+ * @return mixed
860
+ */
861
+ public function iub_ctype() {
862
+ echo '
863
+ <div id="iub_ctype_container">
864
+ <label><input id="iub_ctype" type="checkbox" name="iubenda_cookie_law_solution[ctype]" value="1" ' . checked( true, (bool) iubenda()->options['cs']['ctype'], false ) . '/>' . __( 'Restrict the plugin to run only for requests that have "Content-type: text / html" (recommended)', 'iubenda' ) . '</label>
865
+ </div>';
866
+ }
867
+
868
+ /**
869
+ * RSS feed option.
870
+ *
871
+ * @return mixed
872
+ */
873
+ public function iub_output_feed() {
874
+ echo '
875
+ <div id="iub_output_feed_container">
876
+ <label><input id="iub_output_feed" type="checkbox" name="iubenda_cookie_law_solution[output_feed]" value="1" ' . checked( true, (bool) iubenda()->options['cs']['output_feed'], false ) . '/>' . __( 'Do not run the plugin inside the RSS feed (recommended)', 'iubenda' ) . '</label>
877
+ </div>';
878
+ }
879
+
880
+ /**
881
+ * POST request option.
882
+ *
883
+ * @return mixed
884
+ */
885
+ public function iub_output_post() {
886
+ echo '
887
+ <div id="iub_output_post_container">
888
+ <label><input id="iub_output_post" type="checkbox" name="iubenda_cookie_law_solution[output_post]" value="1" ' . checked( true, (bool) iubenda()->options['cs']['output_post'], false ) . '/>' . __( 'Do not run the plugin on POST requests (recommended)', 'iubenda' ) . '</label>
889
+ </div>';
890
+ }
891
+
892
+ /**
893
+ * Menu option.
894
+ *
895
+ * @return mixed
896
+ */
897
+ public function iub_menu_position() {
898
+ echo '
899
+ <div id="iub_menu_position_container">
900
+ <label><input id="iub_menu_position-topmenu" type="radio" name="iubenda_cookie_law_solution[menu_position]" value="topmenu" ' . checked( 'topmenu', iubenda()->options['cs']['menu_position'], false ) . ' />' . __( 'Top menu', 'iubenda' ) . '</label>
901
+ <label><input id="iub_menu_position-submenu" type="radio" name="iubenda_cookie_law_solution[menu_position]" value="submenu" ' . checked( 'submenu', iubenda()->options['cs']['menu_position'], false ) . ' />' . __( 'Submenu', 'iubenda' ) . '</label>
902
+ <p class="description">' . __( 'Select whether to display iubenda in a top admin menu or the Settings submenu.', 'iubenda' ) . '</p>
903
+ </div>';
904
+ }
905
+
906
+ /**
907
+ * Google AMP support option.
908
+ *
909
+ * @return mixed
910
+ */
911
+ public function iub_amp_support() {
912
+ echo '
913
+ <div id="iub_amp_support_container">
914
+ <label><input id="iub_amp_support" type="checkbox" name="iubenda_cookie_law_solution[amp_support]" value="1" ' . checked( true, (bool) iubenda()->options['cs']['amp_support'], false ) . '/>' . __( 'Enable Google AMP support.', 'iubenda' ) . '</label>
915
+ <p class="description">' . sprintf( __( 'This feature enables iubenda on AMP pages via the <a href="%s" target="_blank">AMP</a> and <a href="%s" target="_blank">AMP for WP</a> plugins. AMP requires specific configuration parameters and a page hosted on your domain where the configuration is loaded from. <a href="%s" target="_blank">Learn more on iubenda and AMP</a>.', 'iubenda' ), 'https://wordpress.org/plugins/amp/', 'https://wordpress.org/plugins/accelerated-mobile-pages/', 'https://www.iubenda.com/en/help/22135-cookie-solution-amp#wordpress' ) . '</p>
916
+ <div id="iub_amp_options_container"' . ( iubenda()->options['cs']['amp_support'] === false ? ' style="display: none;"' : '' ) . '>
917
+ <div>
918
+ <label><input id="iub_amp_source-local" class="iub_amp_source" type="radio" name="iubenda_cookie_law_solution[amp_source]" value="local" ' . checked( 'local', iubenda()->options['cs']['amp_source'], false ) . ' />' . __( 'Auto-generated configuration file', 'iubenda' ) . '</label>
919
+ <label><input id="iub_amp_source-remote" class="iub_amp_source" type="radio" name="iubenda_cookie_law_solution[amp_source]" value="remote" ' . checked( 'remote', iubenda()->options['cs']['amp_source'], false ) . ' />' . __( 'Custom configuration file', 'iubenda' ) . '</label>
920
+ <p class="description">' . __( 'Select the iubenda AMP configuration file location.', 'iubenda' ) . '</p>
921
+ </div>
922
+ <div id="iub_amp_template-local"' . ( iubenda()->options['cs']['amp_source'] === 'remote' ? ' style="display: none;"' : '' ) . '>';
923
+ if ( empty( iubenda()->options['cs']['amp_template_done'] ) ) {
924
+ echo '
925
+ <p class="description">' . __( 'No file available. Save changes to generate iubenda AMP configuration file.', 'iubenda' ) . '</p>';
926
+ } else {
927
+ // multilang support
928
+ if ( iubenda()->multilang && ! empty( iubenda()->languages ) ) {
929
+ foreach ( iubenda()->languages as $lang_id => $lang_name ) {
930
+ echo $lang_name . ':
931
+ <a href="' . iubenda()->AMP->get_amp_template_url( $lang_id ) . '" target="_blank">' . iubenda()->AMP->get_amp_template_url( $lang_id ) . '</a><br />';
932
+ }
933
+ } else {
934
+ echo '
935
+ <a href="' . iubenda()->AMP->get_amp_template_url() . '" target="_blank">' . iubenda()->AMP->get_amp_template_url() . '</a>';
936
+ }
937
+ }
938
+ echo '
939
+ </div>
940
+ <div id="iub_amp_template-remote"' . ( iubenda()->options['cs']['amp_source'] === 'local' ? ' style="display: none;"' : '' ) . '>';
941
+
942
+ // multilang support
943
+ if ( iubenda()->multilang && ! empty( iubenda()->languages ) ) {
944
+ foreach ( iubenda()->languages as $lang_id => $lang_name ) {
945
+ echo $lang_name . ':
946
+ <label><input id="iub_amp_template-' . $lang_id . '" type="text" class="regular-text" name="iubenda_cookie_law_solution[amp_template][' . $lang_id . ']" value="' . ( isset( iubenda()->options['cs']['amp_template'][$lang_id] ) ? esc_url( iubenda()->options['cs']['amp_template'][$lang_id] ) : '' ) . '" /></label><br />';
947
+ }
948
+ } else {
949
+ echo '
950
+ <label><input id="iub_amp_template" type="text" class="regular-text" name="iubenda_cookie_law_solution[amp_template]" value="' . ( isset( iubenda()->options['cs']['amp_template'] ) ? esc_url( iubenda()->options['cs']['amp_template'] ) : '' ) . '" /></label>';
951
+ }
952
+ echo '
953
+ <p class="description">' . __( 'If you\'re experiencing issues with AMP setup download the generated iubenda AMP configuration file, upload it to any SSL server and paste the file link to the field above.', 'iubenda' ) . '</p>
954
+ </div>
955
+ <p class="description">' . sprintf( __( 'Seeing the AMP cookie notice when testing from Google but not when visiting your AMP pages directly? <a href="%s" target="_blank">Learn how to fix it</a>.', 'iubenda' ), 'https://www.iubenda.com/en/help/3182-cookie-solution-amp#amp-domain' ) . '</p>
956
+ </div>
957
+ </div>';
958
+ }
959
+
960
+ /**
961
+ * Deactivation option.
962
+ *
963
+ * @return mixed
964
+ */
965
+ public function iub_deactivation() {
966
+ echo '
967
+ <div id="iub_deactivation_container">
968
+ <label><input id="iub_deactivation" type="checkbox" name="iubenda_cookie_law_solution[deactivation]" value="1" ' . checked( true, (bool) iubenda()->options['cs']['deactivation'], false ) . '/>' . __( 'Delete all plugin data upon deactivation', 'iubenda' ) . '</label>
969
+ </div>';
970
+ }
971
+
972
+ /**
973
+ * Public API Key option.
974
+ *
975
+ * @return mixed
976
+ */
977
+ public function iub_public_api_key() {
978
+ echo '
979
+ <div id="iub_public_api_key_container">
980
+ <label><input id="iub_public_api_key" type="text" class="regular-text" name="iubenda_consent_solution[public_api_key]" value="' . iubenda()->options['cons']['public_api_key'] . '" /></label>
981
+ <p class="description">' . __( 'Enter your iubenda Javascript library public API key.', 'iubenda' ) . '</p>
982
+ </div>';
983
+ }
984
+
985
+ /**
986
+ * Forms list.
987
+ *
988
+ * @return mixed
989
+ */
990
+ public function iubenda_consent_forms() {
991
+ $form_id = ! empty( $_GET['form_id'] ) ? absint( $_GET['form_id'] ) : 0;
992
+ $form = ! empty( $form_id ) ? iubenda()->forms->get_form( $form_id ) : false;
993
+
994
+ $supported_forms = iubenda()->forms->sources;
995
+
996
+ echo '
997
+ <p class="description">' . __( 'This section lists the forms available for field mapping. The plugin currently supports & detects: WordPress Comment, Contact Form 7, WooCommerce Checkout and WP Forms.', 'iubenda' ) . '</p>';
998
+
999
+ // list screen
1000
+ if ( ! class_exists( 'WP_List_Table' ) )
1001
+ include_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
1002
+
1003
+ include_once( IUBENDA_PLUGIN_PATH . '/includes/forms-list-table.php' );
1004
+
1005
+ $list_table = new iubenda_List_Table_Forms();
1006
+
1007
+ echo '
1008
+ <div id="iubenda-consent-forms">';
1009
+ $list_table->views();
1010
+ $list_table->prepare_items();
1011
+ $list_table->display();
1012
+
1013
+ echo '
1014
+ </div>';
1015
+ }
1016
+
1017
+ /**
1018
+ * Single form.
1019
+ *
1020
+ * @return mixed
1021
+ */
1022
+ public function iubenda_consent_form() {
1023
+ $form_id = ! empty( $_GET['form_id'] ) ? absint( $_GET['form_id'] ) : 0;
1024
+ $form = ! empty( $form_id ) ? iubenda()->forms->get_form( $form_id ) : false;
1025
+
1026
+ if ( ! $form )
1027
+ return;
1028
+
1029
+ $status = isset( $form->post_status ) && in_array( $form->post_status, array_keys( iubenda()->forms->statuses ) ) ? esc_attr( $form->post_status ) : 'publish';
1030
+ $subject = isset( $form->form_subject ) && is_array( $form->form_subject ) ? array_map( 'esc_attr', $form->form_subject ) : array();
1031
+ $preferences = isset( $form->form_preferences ) && is_array( $form->form_preferences ) ? array_map( 'esc_attr', $form->form_preferences ) : array();
1032
+ $exclude = isset( $form->form_exclude ) && is_array( $form->form_exclude ) ? array_map( 'esc_attr', $form->form_exclude ) : array();
1033
+ $legal_notices = isset( $form->form_legal_notices ) && is_array( $form->form_legal_notices ) ? array_map( 'esc_attr', $form->form_legal_notices ) : array();
1034
+
1035
+ $available_fields = array();
1036
+
1037
+ if ( ! empty( $form->form_fields ) && is_array( $form->form_fields ) ) {
1038
+ foreach ( $form->form_fields as $index => $form_field ) {
1039
+ if ( is_array( $form_field ) ) {
1040
+ // print_r( $form_field );
1041
+ $available_fields[] = $form_field['label'] . ' (' . $form_field['type'] . ')';
1042
+ } else {
1043
+ $available_fields[] = $form_field;
1044
+ }
1045
+ }
1046
+ }
1047
+
1048
+ // print_r( $form );
1049
+
1050
+ echo '
1051
+ <div id="poststuff">
1052
+ <div id="post-body" class="metabox-holder columns-2">
1053
+ <div id="post-body-content">
1054
+ <div id="titlediv">
1055
+ <div id="titlewrap">
1056
+ <h1>' . $form->post_title . '</h1>
1057
+ </div>
1058
+ <p class="description">' . sprintf( __( '%s form title.', 'iubenda' ), ( array_key_exists( $form->form_source, iubenda()->forms->sources ) ? iubenda()->forms->sources[$form->form_source] : __( 'Unknown', 'iubenda' ) ) ) . '</p>
1059
+
1060
+ <div style="margin-top: 18px"><strong>' . __( 'Available form fields:', 'iubenda' ) . '</strong><br /><p class="description">' . implode( ', ', $available_fields ) . '</p></div>
1061
+ </div>
1062
+ </div>
1063
+ <div id="postbox-container-1" class="postbox-container">
1064
+ <div id="side-sortables" class="">
1065
+ <div id="submitdiv" class="postbox ">
1066
+ <h3 class="hndle"><span>' . __( 'Publish' ) . '</span></h3>
1067
+ <div class="inside">
1068
+ <div id="submitpost" class="submitbox">
1069
+ <div id="minor-publishing">
1070
+ <div class="misc-pub-section misc-pub-post-status">
1071
+ <label for="status">' . __( 'Status' ) . ':</label>
1072
+ <div id="status-select" class="" style="margin: 3px 0 0;">
1073
+ <select id="status" name="status">';
1074
+ foreach ( iubenda()->forms->statuses as $name => $label ) {
1075
+ echo '
1076
+ <option value="' . $name . '"' . selected( $form->post_status, $name, true ) . '>' . $label . '</option>';
1077
+ }
1078
+ echo '
1079
+ </select>
1080
+ </div>
1081
+ </div>
1082
+ <div id="major-publishing-actions">
1083
+ <div id="delete-action">
1084
+ <a class="submitdelete deletion" href="' . esc_url( add_query_arg( array( 'tab' => 'cons' ), iubenda()->base_url ) ) . '">' . __( 'Cancel' ) . '</a>
1085
+ </div>
1086
+ <div id="publishing-action">
1087
+ <span class="spinner"></span>
1088
+ <input type="hidden" value="' . $form->ID . '" name="form_id">
1089
+ <input id="publish" class="button button-primary button-large" type="submit" value="' . __( 'Save' ) . '" name="save">
1090
+ </div>
1091
+ <div class="clear"></div>
1092
+ </div>
1093
+ </div>
1094
+ </div>
1095
+ </div>
1096
+ </div>
1097
+ </div>
1098
+ </div>
1099
+ <div id="postbox-container-2" class="postbox-container">
1100
+ <div id="normal-sortables" class="meta-box-sortables">
1101
+ <div id="map-fields" class="postbox">
1102
+ <h3 class="hndle ui-sortable-handle"><span>' . __( 'Map fields', 'iubenda' ) . '</span></h3>
1103
+ <div class="inside">
1104
+ <table class="widefat">
1105
+ <tbody>
1106
+ <tr>
1107
+ <td class="label table-label">
1108
+ <h4>' . __( 'Subject fields', 'iubenda' ) . ' <span class="required">(required)</span></h4>
1109
+ <p class="description">' . __( 'Subject fields allow you to store a series of identifying values about your individual subjects/users. Please map the subject field with the corresponding form fields where applicable.', 'iubenda' ) . '</p>
1110
+ </td>
1111
+ <td>
1112
+ <table class="widefat subject-table">
1113
+ <thead>
1114
+ <td class="label">' . __( 'Subject field', 'iubenda' ) . '</td>
1115
+ <td class="label">' . __( 'Form field', 'iubenda' ) . '</td>
1116
+ </thead>
1117
+ <tbody>';
1118
+
1119
+ foreach ( $this->subject_fields as $field_name => $field_label ) {
1120
+ $selected = isset( $subject[$field_name] ) ? $subject[$field_name] : '';
1121
+ $none = $field_name == 'id' ? __( 'Autogenerated', 'iubenda' ) : __( 'None', 'iubenda' );
1122
+
1123
+ echo '
1124
+ <tr class="subject-field options-field">
1125
+ <td>' . $field_name . ' (' . $field_label . ')' . '</td>
1126
+ <td>
1127
+ <select class="subject-fields-select select-' . $field_name . '" name="subject[' . $field_name . ']">
1128
+ <option value="" ' . selected( $selected, '', false ) . '>' . $none . '</option>';
1129
+ if ( ! empty( $form->form_fields ) ) {
1130
+ foreach ( $form->form_fields as $index => $form_field ) {
1131
+ // get field data
1132
+ $form_field_value = is_array( $form_field ) ? $index : $form_field;
1133
+ $form_field_label = is_array( $form_field ) ? $form_field['label'] . ' (' . $form_field['type'] . ')' : $form_field;
1134
+ $form_field_selected = is_array( $form_field ) ? $index : $form_field;
1135
+
1136
+ echo '<option value="' . $form_field_value . '" ' . selected( $selected, $form_field_selected, false ) . '>' . $form_field_label . '</option>';
1137
+ }
1138
+ }
1139
+ echo '
1140
+ </select>
1141
+ </td>
1142
+ </tr>
1143
+ ';
1144
+ }
1145
+ echo '
1146
+ </tbody>
1147
+ </table>
1148
+ </td>
1149
+ </tr>
1150
+ <tr>
1151
+ <td class="label table-label">
1152
+ <h4>' . __( 'Preferences fields', 'iubenda' ) . ' <span class="required">(required)</span></h4>
1153
+ <p class="description">' . __( 'Preferences fields allow you to store a record of the various opt-ins points at which the user has agreed or given consent, such as fields for agreeing to terms and conditions, newsletter, profiling, etc. *Please create at least one preference field.', 'iubenda' ) . '</p>
1154
+ </td>
1155
+ <td>
1156
+ <table class="widefat preferences-table">
1157
+ <thead>
1158
+ <td class="label">' . __( 'Preferences field', 'iubenda' ) . '</td>
1159
+ <td class="label">' . __( 'Form field', 'iubenda' ) . '</td>
1160
+ </thead>
1161
+ <tbody>';
1162
+ echo '
1163
+ <tr id="preferences-field-template" class="template-field" style="display: none;">
1164
+ <td><input type="text" class="regular-text" value="" name="preferences[__PREFERENCE_ID__][field]" placeholder="' . __( 'Enter field name', 'iubenda' ) . '" /></td>
1165
+ <td>
1166
+ <select class="preferences-fields-select select-' . $field_name . '" name="preferences[__PREFERENCE_ID__][value]">';
1167
+ if ( ! empty( $form->form_fields ) ) {
1168
+ foreach ( $form->form_fields as $index => $form_field ) {
1169
+ // get field data
1170
+ $form_field_value = is_array( $form_field ) ? $index : $form_field;
1171
+ $form_field_label = is_array( $form_field ) ? $form_field['label'] . ' (' . $form_field['type'] . ')' : $form_field;
1172
+
1173
+ echo '<option value="' . $form_field_value . '">' . $form_field_label . '</option>';
1174
+ }
1175
+ }
1176
+ echo '
1177
+ </select>
1178
+ <a href="javascript:void(0)" class="remove-preferences-field button-secondary" title="' . __( 'Remove', 'iubenda' ) . '">-</a>
1179
+ </td>
1180
+ </tr>';
1181
+
1182
+ if ( $preferences ) {
1183
+ $index = 0;
1184
+
1185
+ foreach ( $preferences as $field_name => $field_value ) {
1186
+ $selected = isset( $preferences[$field_name] ) ? $preferences[$field_name] : '';
1187
+
1188
+ echo '
1189
+ <tr class="preferences-field options-field">
1190
+ <td><input type="text" class="regular-text" value="' . $field_name . '" name="preferences[' . $index . '][field]" placeholder="' . __( 'Enter field name', 'iubenda' ) . '" /></td>
1191
+ <td>
1192
+ <select class="preferences-fields-select select-' . $field_name . '" name="preferences[' . $index . '][value]">';
1193
+ if ( ! empty( $form->form_fields ) ) {
1194
+ foreach ( $form->form_fields as $index => $form_field ) {
1195
+ // get field data
1196
+ $form_field_value = is_array( $form_field ) ? $index : $form_field;
1197
+ $form_field_label = is_array( $form_field ) ? $form_field['label'] . ' (' . $form_field['type'] . ')' : $form_field;
1198
+ $form_field_selected = is_array( $form_field ) ? $index : $form_field;
1199
+
1200
+ echo '<option value="' . $form_field_value . '" ' . selected( $selected, $form_field_selected, false ) . '>' . $form_field_label . '</option>';
1201
+ }
1202
+ }
1203
+ echo '
1204
+ </select>
1205
+ <a href="javascript:void(0)" class="remove-preferences-field button-secondary" title="' . __( 'Remove', 'iubenda' ) . '">-</a>
1206
+ </td>
1207
+ </tr>';
1208
+
1209
+ $index++;
1210
+ }
1211
+ }
1212
+
1213
+ echo '
1214
+ <tr class="submit-field"><td colspan="2"><a href="javascript:void(0)" class="add-preferences-field button-secondary">' . __( 'Add New Preference', 'iubenda' ) . '</a></td></tr>
1215
+ </tbody>
1216
+ </table>
1217
+ </td>
1218
+ </tr>
1219
+ <tr>
1220
+ <td class="label table-label">
1221
+ <h4>' . __( 'Exclude fields', 'iubenda' ) . '</h4>
1222
+ <p class="description">' . __( 'Exclude fields allow you to create a list of fields that you would like to exclude from your Consent Solution recorded proofs (for e.g. password or other fields not related to the consent).', 'iubenda' ) . '</p>
1223
+ </td>
1224
+ <td>
1225
+ <table class="widefat exclude-table">
1226
+ <thead>
1227
+ <td class="label">' . __( 'Exclude field', 'iubenda' ) . '</td>
1228
+ <td class="label"></td>
1229
+ </thead>
1230
+ <tbody>';
1231
+ echo '
1232
+ <tr id="exclude-field-template" class="template-field" style="display: none;">
1233
+ <td>
1234
+ <select class="exclude-fields-select select-' . $field_name . '" name="exclude[__EXCLUDE_ID__][field]">';
1235
+ if ( ! empty( $form->form_fields ) ) {
1236
+ foreach ( $form->form_fields as $index => $form_field ) {
1237
+ // get field data
1238
+ $form_field_value = is_array( $form_field ) ? $index : $form_field;
1239
+ $form_field_label = is_array( $form_field ) ? $form_field['label'] . ' (' . $form_field['type'] . ')' : $form_field;
1240
+
1241
+ echo '<option value="' . $form_field_value . '">' . $form_field_label . '</option>';
1242
+ }
1243
+ }
1244
+ echo '
1245
+ </select>
1246
+ <a href="javascript:void(0)" class="remove-exclude-field button-secondary" title="' . __( 'Remove', 'iubenda' ) . '">-</a>
1247
+ </td>
1248
+ <td></td>
1249
+
1250
+ </tr>';
1251
+
1252
+ if ( $exclude ) {
1253
+ $index = 0;
1254
+
1255
+ foreach ( $exclude as $index => $field_name ) {
1256
+ $selected = isset( $exclude[$index] ) ? $exclude[$index] : '';
1257
+
1258
+ echo '
1259
+ <tr class="exclude-field options-field">
1260
+ <td>
1261
+ <select class="exclude-fields-select select-' . $field_name . '" name="exclude[' . $index . '][field]">';
1262
+ if ( ! empty( $form->form_fields ) ) {
1263
+ foreach ( $form->form_fields as $index => $form_field ) {
1264
+ // get field data
1265
+ $form_field_value = is_array( $form_field ) ? $index : $form_field;
1266
+ $form_field_label = is_array( $form_field ) ? $form_field['label'] . ' (' . $form_field['type'] . ')' : $form_field;
1267
+ $form_field_selected = is_array( $form_field ) ? $index : $form_field;
1268
+
1269
+ echo '<option value="' . $form_field_value . '" ' . selected( $selected, $form_field_selected, false ) . '>' . $form_field_label . '</option>';
1270
+ }
1271
+ }
1272
+ echo '
1273
+ </select>
1274
+ <a href="javascript:void(0)" class="remove-exclude-field button-secondary" title="' . __( 'Remove', 'iubenda' ) . '">-</a>
1275
+ </td>
1276
+ <td></td>
1277
+ </tr>';
1278
+
1279
+ $index++;
1280
+ }
1281
+ }
1282
+
1283
+ echo '
1284
+ <tr class="submit-field"><td colspan="2"><a href="javascript:void(0)" class="add-exclude-field button-secondary">' . __( 'Add New Exclude', 'iubenda' ) . '</a></td></tr>
1285
+ </tbody>
1286
+ </table>
1287
+ </td>
1288
+ </tr>
1289
+ </tbody>
1290
+ </table>
1291
+ </div>
1292
+ </div>
1293
+ <div id="legal-notices" class="postbox">
1294
+ <h3 class="hndle ui-sortable-handle"><span>' . __( 'Legal Notices', 'iubenda' ) . '</span></h3>
1295
+ <div class="inside">
1296
+ <table class="widefat">
1297
+ <tbody>
1298
+ <tr>
1299
+ <td class="label table-label">
1300
+ <h4>' . __( 'Legal documents', 'iubenda' ) . '</h4>
1301
+ <p class="description">' . __( 'In general, it\'s important that you declare which legal documents are being agreed upon when each consent is collected. However, if you use iubenda for your legal documents, it is *required* that you identify the documents by selecting them here.', 'iubenda' ) . '</p>
1302
+ </td>
1303
+ <td>
1304
+ <table class="widefat legal_notices-table">
1305
+ <thead>
1306
+ <td class="label">' . __( 'Identifier', 'iubenda' ) . '</td>
1307
+ <td class="label"></td>
1308
+ </thead>
1309
+ <tbody>';
1310
+
1311
+ // default identifiers
1312
+ foreach ( $this->legal_notices as $index => $field_name ) {
1313
+ echo '
1314
+ <tr class="legal_notices-field default-field">
1315
+ <td>' . ( $index === 0 ? '<p class="description">' . __( 'Please select each legal document available on your site.', 'iubenda' ) . '</p>' : '' ) . '<label for="legal_notices-default-field=' . $index . '"><input id="legal_notices-default-field=' . $index . '" type="checkbox" value="' . $field_name . '" name="legal_notices[' . $index . '][field]"' . checked( in_array( $field_name, $legal_notices, true ), true, false ) . 'placeholder="' . __( 'Enter field name', 'iubenda' ) . '" />' . $field_name . '</label></td>
1316
+ <td></td>
1317
+ </tr>';
1318
+ }
1319
+
1320
+ $index++;
1321
+
1322
+ // custom identifiers
1323
+ echo '
1324
+ <tr id="legal_notices-field-template" class="template-field" style="display: none;">
1325
+ <td><input type="text" class="regular-text" value="" name="legal_notices[__LEGAL_NOTICE_ID__][field]" placeholder="' . __( 'Enter field name', 'iubenda' ) . '" /> <a href="javascript:void(0)" class="remove-legal_notices-field button-secondary" title="' . __( 'Remove', 'iubenda' ) . '">-</a></td>
1326
+ <td></td>
1327
+ </tr>';
1328
+
1329
+ echo '
1330
+ <tr>
1331
+ <td colspan="2"><p class="description" style="margin-bottom: 0;">' . __( 'Alternatively, you may add your own custom document identifiers.', 'iubenda' ) . '</p></td>
1332
+ </tr>';
1333
+
1334
+ if ( $legal_notices ) {
1335
+ foreach ( $legal_notices as $field_name ) {
1336
+ if ( in_array( $field_name, $this->legal_notices, true ) )
1337
+ continue;
1338
+
1339
+ echo '
1340
+ <tr class="legal_notices-field options-field">
1341
+ <td><input type="text" class="regular-text" value="' . $field_name . '" name="legal_notices[' . $index . '][field]" placeholder="' . __( 'Enter field name', 'iubenda' ) . '" /> <a href="javascript:void(0)" class="remove-legal_notices-field button-secondary" title="' . __( 'Remove', 'iubenda' ) . '">-</a></td>
1342
+ <td></td>
1343
+ </tr>';
1344
+
1345
+ $index++;
1346
+ }
1347
+ }
1348
+
1349
+ echo '
1350
+ <tr class="submit-field"><td colspan="2"><a href="javascript:void(0)" class="add-legal_notices-field button-secondary">' . __( 'Add New Document', 'iubenda' ) . '</a></td></tr>';
1351
+ echo '
1352
+ </tbody>
1353
+ </table>
1354
+ </td>
1355
+ </tr>
1356
+ </tbody>
1357
+ </table>
1358
+ </div>
1359
+ </div>
1360
+ </div>
1361
+ </div>
1362
+ </div>
1363
+ </div>
1364
+ <div class="clear"></div>';
1365
+
1366
+ // echo '<pre>'; print_r( $form ); echo '</pre>';
1367
+ }
1368
+
1369
+ /**
1370
+ * Save cookie solution options.
1371
+ *
1372
+ * @return void
1373
+ */
1374
+ public function save_cookie_law_options( $input ) {
1375
+ if ( ! current_user_can( apply_filters( 'iubenda_cookie_law_cap', 'manage_options' ) ) )
1376
+ return $input;
1377
+
1378
+ // save options
1379
+ if ( isset( $_POST['save_iubenda_options'] ) ) {
1380
+ $input['parse'] = (bool) isset( $input['parse'] );
1381
+ $input['parser_engine'] = isset( $input['parser_engine'] ) && in_array( $input['parser_engine'], array( 'default', 'new' ) ) ? $input['parser_engine'] : iubenda()->defaults['cs']['parser_engine'];
1382
+ $input['skip_parsing'] = (bool) isset( $input['skip_parsing'] );
1383
+ $input['ctype'] = (bool) isset( $input['ctype'] );
1384
+ $input['output_feed'] = (bool) isset( $input['output_feed'] );
1385
+ $input['output_post'] = (bool) isset( $input['output_post'] );
1386
+ $input['menu_position'] = isset( $input['menu_position'] ) && in_array( $input['menu_position'], array( 'topmenu', 'submenu' ) ) ? $input['menu_position'] : iubenda()->defaults['cs']['menu_position'];
1387
+ $input['amp_support'] = (bool) isset( $input['amp_support'] );
1388
+ $input['deactivation'] = (bool) isset( $input['deactivation'] );
1389
+
1390
+ // multilang support
1391
+ if ( iubenda()->multilang && ! empty( iubenda()->languages ) ) {
1392
+ $iubenda_code = array();
1393
+
1394
+ foreach ( iubenda()->languages as $lang_id => $lang_name ) {
1395
+ $input['code_' . $lang_id] = $iubenda_code[$lang_id] = ! empty( $input['code_' . $lang_id] ) ? iubenda()->parse_code( $input['code_' . $lang_id] ) : '';
1396
+
1397
+ // handle default lang too
1398
+ if ( $lang_id == iubenda()->lang_default ) {
1399
+ $input['code_default'] = ! empty( $input['code_' . $lang_id] ) ? iubenda()->parse_code( $input['code_' . $lang_id] ) : iubenda()->options['cs']['code_default'];
1400
+ }
1401
+ }
1402
+ } else {
1403
+ $iubenda_code = '';
1404
+
1405
+ $input['code_default'] = $iubenda_code = ! empty( $input['code_default'] ) ? iubenda()->parse_code( $input['code_default'] ) : '';
1406
+ }
1407
+
1408
+ // generate amp template file
1409
+ if ( isset( $input['amp_support'] ) ) {
1410
+ $template_done = false;
1411
+
1412
+ if ( ! empty( $iubenda_code ) ) {
1413
+ if ( is_array( $iubenda_code ) ) {
1414
+ $template_done = array();
1415
+
1416
+ foreach ( $iubenda_code as $lang => $code ) {
1417
+ $template_done[$lang] = (bool) iubenda()->AMP->generate_amp_template( $code, $lang );
1418
+ }
1419
+ } else {
1420
+ $template_done = (bool) iubenda()->AMP->generate_amp_template( $iubenda_code );
1421
+ }
1422
+ }
1423
+
1424
+ $input['amp_template_done'] = $template_done;
1425
+
1426
+ if ( is_array( $input['amp_template'] ) ) {
1427
+ foreach ( $input['amp_template'] as $lang => $template ) {
1428
+ $input['amp_template'][$lang] = esc_url( $template );
1429
+ }
1430
+ } else {
1431
+ $input['amp_template'] = esc_url( $input['amp_template'] );
1432
+ }
1433
+ }
1434
+
1435
+ // scripts
1436
+ if ( ! empty( $input['custom_scripts'] ) && ! empty( $input['custom_scripts']['script'] ) && ! empty( $input['custom_scripts']['type'] ) ) {
1437
+ $scripts = array();
1438
+
1439
+ // first field is template
1440
+ if ( count( $input['custom_scripts']['script'] ) > 1 ) {
1441
+ foreach ( $input['custom_scripts']['script'] as $number => $script ) {
1442
+ $trimmed = trim( $script );
1443
+
1444
+ if ( $trimmed !== '' )
1445
+ $scripts[$trimmed] = (int) $input['custom_scripts']['type'][$number];
1446
+ }
1447
+ }
1448
+
1449
+ $input['custom_scripts'] = $scripts;
1450
+ } else
1451
+ $input['custom_scripts'] = array();
1452
+
1453
+ // iframes
1454
+ if ( ! empty( $input['custom_iframes'] ) && ! empty( $input['custom_iframes']['iframe'] ) && ! empty( $input['custom_iframes']['type'] ) ) {
1455
+ $iframes = array();
1456
+
1457
+ // first field is template
1458
+ if ( count( $input['custom_iframes']['iframe'] ) > 1 ) {
1459
+ foreach ( $input['custom_iframes']['iframe'] as $number => $iframe ) {
1460
+ $trimmed = trim( $iframe );
1461
+
1462
+ if ( $trimmed !== '' )
1463
+ $iframes[$trimmed] = (int) $input['custom_iframes']['type'][$number];
1464
+ }
1465
+ }
1466
+
1467
+ $input['custom_iframes'] = $iframes;
1468
+ } else
1469
+ $input['custom_iframes'] = array();
1470
+
1471
+ add_settings_error( 'cs_settings_errors', 'iub_cs_settings_updated', __( 'Settings saved.', 'iubenda' ), 'updated' );
1472
+ // reset options
1473
+ } elseif ( isset( $_POST['reset_iubenda_options'] ) ) {
1474
+ $input = iubenda()->defaults['cs'];
1475
+
1476
+ // multilang support
1477
+ if ( iubenda()->multilang && ! empty( iubenda()->languages ) ) {
1478
+ foreach ( iubenda()->languages as $lang_id => $lang_name ) {
1479
+ $input['code_' . $lang_id] = '';
1480
+ }
1481
+ }
1482
+
1483
+ add_settings_error( 'cs_settings_errors', 'iub_cs_settings_restored', __( 'Settings restored to defaults.', 'iubenda' ), 'updated' );
1484
+ }
1485
+
1486
+ return $input;
1487
+ }
1488
+
1489
+ /**
1490
+ * Save consent solution options.
1491
+ *
1492
+ * @return void
1493
+ */
1494
+ public function save_consent_options( $input ) {
1495
+
1496
+ if ( ! current_user_can( apply_filters( 'iubenda_cookie_law_cap', 'manage_options' ) ) )
1497
+ return $input;
1498
+
1499
+ // save options
1500
+ if ( isset( $_POST['save_consent_options'] ) ) {
1501
+ $input['public_api_key'] = isset( $input['public_api_key'] ) ? esc_attr( $input['public_api_key'] ) : '';
1502
+
1503
+ add_settings_error( 'cons_settings_errors', 'iub_cons_settings_updated', __( 'Settings saved.', 'iubenda' ), 'updated' );
1504
+ // reset options
1505
+ } elseif ( isset( $_POST['reset_consent_options'] ) ) {
1506
+ $input = iubenda()->defaults['cons'];
1507
+
1508
+ add_settings_error( 'cons_settings_errors', 'iub_cons_settings_restored', __( 'Settings restored to defaults.', 'iubenda' ), 'updated' );
1509
+ }
1510
+
1511
+ return $input;
1512
+ }
1513
+
1514
+ /**
1515
+ * Process the bulk actions
1516
+ *
1517
+ * @return void
1518
+ */
1519
+ public function process_actions() {
1520
+ global $pagenow;
1521
+
1522
+ $page = ! empty( $_POST['option_page'] ) ? esc_attr( $_POST['option_page'] ) : ( ! empty( $_GET['page'] ) ? esc_attr( $_GET['page'] ) : '' );
1523
+ $id = isset( $_REQUEST['form_id'] ) ? ( is_array( $_REQUEST['form_id'] ) ? array_map( 'ansint', $_REQUEST['form_id'] ) : absint( $_REQUEST['form_id'] ) ) : false;
1524
+ $tab_key = ! empty( $_GET['tab'] ) ? esc_attr( $_GET['tab'] ) : 'cs';
1525
+
1526
+ if ( ! $page )
1527
+ return;
1528
+
1529
+ // get redirect url
1530
+ if ( iubenda()->options['cs']['menu_position'] === 'submenu' && $pagenow === 'admin.php' ) {
1531
+ // sub menu
1532
+ $redirect_to = admin_url( 'options-general.php?page=iubenda&tab=' . $tab_key );
1533
+ } else {
1534
+ // top menu
1535
+ $redirect_to = admin_url( 'admin.php?page=iubenda&tab=' . $tab_key );
1536
+ }
1537
+
1538
+ // add comments cookie option notice
1539
+ if ( $tab_key != 'cs' && ! empty( iubenda()->options['cons']['public_api_key'] ) ) {
1540
+ $cookies_enabled = get_option( 'show_comments_cookies_opt_in' );
1541
+
1542
+ if ( ! $cookies_enabled ) {
1543
+ $this->add_notice( 'iub_comment_cookies_disabled', sprintf( __( 'Please enable comments cookies opt-in checkbox in the <a href="%s" target="_blank">Discussion settings</a>.', 'iubenda' ), esc_url( admin_url( 'options-discussion.php' ) ) ), 'notice' );
1544
+ }
1545
+ }
1546
+
1547
+ $result = null;
1548
+
1549
+ switch ( $this->action ) {
1550
+ case 'autodetect' :
1551
+ $result = iubenda()->forms->autodetect_forms();
1552
+
1553
+ // new forms notice
1554
+ if ( ! empty( $result['new'] ) )
1555
+ $this->add_notice( 'iub_autodetect_success', sprintf( _n( '%d form detected successfully.', '%d forms detected successfully.', count( $result['new'] ), 'iubenda' ), $result ), 'success' );
1556
+
1557
+ // forms changed notice
1558
+ if ( ! empty( $result['updated'] ) )
1559
+ $this->add_notice( 'iub_autodetect_success', sprintf( _n( '%d form change detected.', '%d form changes detected.', count( $result['updated'] ), 'iubenda' ), $result ), 'success' );
1560
+
1561
+ // no changes notice
1562
+ if ( empty( $result['new'] ) && empty( $result['updated'] ) )
1563
+ $this->add_notice( 'iub_autodetect_success', __( 'No forms or form changes detected.', 'iubenda' ), 'error' );
1564
+
1565
+ // make sure it's current host location
1566
+ wp_safe_redirect( $redirect_to );
1567
+ exit;
1568
+
1569
+ break;
1570
+
1571
+ case 'save' :
1572
+ if ( ! $id )
1573
+ return;
1574
+
1575
+ $form = iubenda()->forms->get_form( $id );
1576
+
1577
+ if ( $form->ID != $id )
1578
+ return;
1579
+
1580
+ $status = isset( $_POST['status'] ) && in_array( $_POST['status'], array_keys( iubenda()->forms->statuses ) ) ? esc_attr( $_POST['status'] ) : 'publish';
1581
+ $subject = isset( $_POST['subject'] ) && is_array( $_POST['subject'] ) ? array_map( 'esc_attr', $_POST['subject'] ) : array();
1582
+ $preferences = array();
1583
+ $exclude = array();
1584
+ $legal_notices = array();
1585
+
1586
+ $preferences_raw = isset( $_POST['preferences'] ) && is_array( $_POST['preferences'] ) ? array_map( array( $this, 'array_map_callback' ), $_POST['preferences'] ) : array();
1587
+ $exclude_raw = isset( $_POST['exclude'] ) && is_array( $_POST['exclude'] ) ? array_map( array( $this, 'array_map_callback' ), $_POST['exclude'] ) : array();
1588
+ $legal_notices_raw = isset( $_POST['legal_notices'] ) && is_array( $_POST['legal_notices'] ) ? array_map( array( $this, 'array_map_callback' ), $_POST['legal_notices'] ) : array();
1589
+
1590
+ // format preferences data
1591
+ if ( ! empty( $preferences_raw ) && is_array( $preferences_raw ) ) {
1592
+ foreach ( $preferences_raw as $index => $data ) {
1593
+ if ( ! empty( $data['field'] ) && ! empty( $data['value'] ) )
1594
+ $preferences[ sanitize_key( $data['field'] ) ] = $data['value'];
1595
+ }
1596
+ }
1597
+
1598
+ // format exclude data
1599
+ if ( ! empty( $exclude_raw ) && is_array( $exclude_raw ) ) {
1600
+ foreach ( $exclude_raw as $index => $data ) {
1601
+ if ( ! empty( $data['field'] ) )
1602
+ $exclude[] = $data['field'];
1603
+ }
1604
+ }
1605
+
1606
+ // format legal notices data
1607
+ if ( ! empty( $legal_notices_raw ) && is_array( $legal_notices_raw ) ) {
1608
+ foreach ( $legal_notices_raw as $index => $data ) {
1609
+ if ( ! empty( $data['field'] ) )
1610
+ $legal_notices[] = $data['field'];
1611
+ }
1612
+ }
1613
+
1614
+ // form first save, update status to mapped automatically
1615
+ if ( empty( $form->form_subject ) && empty( $form->form_preferences ) ) {
1616
+ $status = 'mapped';
1617
+ }
1618
+
1619
+ // echo '<pre>'; print_r( $_POST ); echo '</pre>'; exit;
1620
+
1621
+ // bail if empty fields
1622
+ if ( empty( $subject ) || empty( $preferences ) ) {
1623
+ $this->add_notice( 'iub_form_fields_missing', __( 'Form saving failed. Please fill the Subject and Preferences fields.', 'iubenda' ), 'error' );
1624
+ return;
1625
+ }
1626
+
1627
+ $args = array(
1628
+ 'ID' => $form->ID,
1629
+ 'status' => $status,
1630
+ 'object_type' => $form->object_type,
1631
+ 'object_id' => $form->object_id,
1632
+ 'form_source' => $form->form_source,
1633
+ 'form_title' => $form->post_title,
1634
+ 'form_date' => $form->post_modified,
1635
+ 'form_fields' => $form->form_fields,
1636
+ 'form_subject' => $subject,
1637
+ 'form_preferences' => $preferences,
1638
+ 'form_exclude' => $exclude,
1639
+ 'form_legal_notices' => $legal_notices
1640
+ );
1641
+
1642
+ $result = iubenda()->forms->save_form( $args );
1643
+
1644
+ if ( $result ) {
1645
+ // form save, inform about form status update
1646
+ if ( empty( $form->form_subject ) && empty( $form->form_preferences ) ) {
1647
+ $this->add_notice( 'iub_form_saved', __( 'Form saved successfully - form status changed to Mapped.', 'iubenda' ), 'success' );
1648
+ // form update
1649
+ } else {
1650
+ $this->add_notice( 'iub_form_updated', __( 'Form updated successfully.', 'iubenda' ), 'success' );
1651
+ }
1652
+ } else {
1653
+ $this->add_notice( 'iub_form_failed', __( 'Form saving failed.', 'iubenda' ), 'error' );
1654
+ }
1655
+
1656
+ break;
1657
+
1658
+ case 'delete' :
1659
+ if ( ! $id )
1660
+ return;
1661
+
1662
+ $form = iubenda()->forms->get_form( $id );
1663
+
1664
+ if ( empty( $form ) )
1665
+ return;
1666
+
1667
+ $result = iubenda()->forms->delete_form( $id );
1668
+
1669
+ if ( $result )
1670
+ $this->add_notice( 'iub_form_deleted', __( 'Form deleted successfully.', 'iubenda' ), 'success' );
1671
+ else
1672
+ $this->add_notice( 'iub_form_delete_failed', __( 'Form delete failed.', 'iubenda' ), 'error' );
1673
+
1674
+ // make sure it's current host location
1675
+ wp_safe_redirect( $redirect_to );
1676
+ exit;
1677
+
1678
+ break;
1679
+
1680
+ case 'disable_skip_parsing' :
1681
+
1682
+ // disable skip parsing option
1683
+ $options = iubenda()->options['cs'];
1684
+ $options['skip_parsing'] = false;
1685
+
1686
+ update_option( 'iubenda_cookie_law_solution', $options );
1687
+
1688
+ $this->add_notice( 'iub_settings_updated', __( 'Settings saved.', 'iubenda' ), 'success' );
1689
+
1690
+ // make sure it's current host location
1691
+ wp_safe_redirect( $redirect_to );
1692
+ exit;
1693
+
1694
+ break;
1695
+
1696
+ default :
1697
+ return;
1698
+ }
1699
+
1700
+ if ( ! empty ( $result ) ) {
1701
+ //
1702
+ } else {
1703
+ //
1704
+ }
1705
+ }
1706
+
1707
+ /**
1708
+ * Add admin notice.
1709
+ *
1710
+ * @param mixed $message
1711
+ * @param string $notice_type
1712
+ */
1713
+ public function add_notice( $key, $message, $notice_type = 'notice' ) {
1714
+ $key = ! empty( $key ) ? sanitize_key( $key ) : '';
1715
+ $message = ! empty( $message ) ? wp_kses_post( $message ) : '';
1716
+ $notice_type = ! empty( $notice_type ) && in_array( $notice_type, $this->notice_types ) ? $notice_type : 'notice';
1717
+
1718
+ if ( ! $key || ! $message )
1719
+ return;
1720
+
1721
+ $notices = get_transient( 'iubenda_dashboard_notices' );
1722
+ $delay = MINUTE_IN_SECONDS * 2;
1723
+
1724
+ if ( empty( $notices ) || ! array_key_exists( $key, $notices[$notice_type] ) ) {
1725
+ $notices[$notice_type][$key] = $message;
1726
+
1727
+ set_transient( 'iubenda_dashboard_notices', $notices, $delay );
1728
+ }
1729
+ }
1730
+
1731
+ /**
1732
+ * Display admin notices.
1733
+ *
1734
+ * @return mixed
1735
+ */
1736
+ public function print_notices() {
1737
+ $notices = get_transient( 'iubenda_dashboard_notices' );
1738
+ $notices_array = array();
1739
+
1740
+ foreach ( $this->notice_types as $notice_type ) {
1741
+ if ( $this->notice_count( $notices, $notice_type ) > 0 ) {
1742
+ echo '<div class="notice notice-' . ( $notice_type === 'notice' ? 'info' : $notice_type ) . ' below-h2 is-dismissible">';
1743
+
1744
+ foreach ( $notices[$notice_type] as $key => $notice ) {
1745
+ echo '<p><strong>' . wp_kses_post( $notice ) . '</strong></p>';
1746
+ }
1747
+
1748
+ echo '<button type="button" class="notice-dismiss"><span class="screen-reader-text">' . __( 'Dismiss this notice.' ) . '</span></button>';
1749
+
1750
+ echo '</div>';
1751
+ }
1752
+ }
1753
+
1754
+ delete_transient( 'iubenda_dashboard_notices' );
1755
+ }
1756
+
1757
+ /**
1758
+ * Count notices function.
1759
+ *
1760
+ * @param string $notice_type
1761
+ * @return int
1762
+ */
1763
+ public function notice_count( $all_notices = array(), $notice_type = '' ) {
1764
+ $notice_count = 0;
1765
+
1766
+ if ( isset( $all_notices[$notice_type] ) ) {
1767
+ $notice_count = absint( sizeof( $all_notices[$notice_type] ) );
1768
+ } elseif ( empty( $notice_type ) ) {
1769
+ foreach ( $all_notices as $notices ) {
1770
+ $notice_count += absint( sizeof( $all_notices ) );
1771
+ }
1772
+ }
1773
+
1774
+ return $notice_count;
1775
+ }
1776
+
1777
+ /**
1778
+ * Adjust highlighted menu.
1779
+ *
1780
+ * @param type $file
1781
+ * @return type
1782
+ */
1783
+ public function submenu_file( $submenu_file, $parent_file ) {
1784
+ global $menu, $submenu;
1785
+
1786
+ if ( $parent_file == 'iubenda' ) {
1787
+ $tab_key = ! empty( $_GET['tab'] ) ? esc_attr( $_GET['tab'] ) : 'cs';
1788
+
1789
+ if ( $tab_key == 'cons' ) {
1790
+ $submenu_file = 'admin.php?page=iubenda&tab=cons';
1791
+ $submenu['iubenda'][1][2] = 'admin.php?page=iubenda&tab=cons';
1792
+ }
1793
+ }
1794
+
1795
+ return $submenu_file;
1796
+ }
1797
+
1798
+ /**
1799
+ * Sanitize array helper function.
1800
+ *
1801
+ * @param array $array
1802
+ * @return array
1803
+ */
1804
+ public function array_map_callback( $array ) {
1805
+ if ( ! is_array( $array ) )
1806
+ return array();
1807
+
1808
+ return array_map( 'esc_attr', $array );
1809
+ }
1810
+
1811
+ }
iubenda-cookie-class/README.md CHANGED
@@ -1,135 +1,135 @@
1
- # Read Me
2
-
3
- ***PHP class for the iubenda cookie law solution***
4
-
5
- If you have European users you need to obtain and manage consent for the use of most cookies.
6
- The iubenda Cookie Solution is an all-in-one approach developed by iubenda, that helps to make your website GDPR and Cookie Law compliant by integrating with your cookie policy, providing a compliant cookie banner and the blocking management of cookie scripts. The Cookie Solution also allows users to set advertising preferences on-site and within the solution, facilitated the recent-but-widely adopted IAB Europe Transparency & Consent [framework](https://www.iubenda.com/en/help/7440#aboutIAB).
7
-
8
- [Read more about the Cookie Solution here](https://www.iubenda.com/en/features#cookie-solution).
9
-
10
- * * *
11
- #### This class allows you to scan a page in PHP for scripts and run the automatic blocking of scripts
12
-
13
- *This is the class on which our WordPress and Joomla! and Drupal plugins are based and you can use it to build your own plugin independently for a platform other than those for which we have already developed a dedicated solution.*
14
-
15
- * * *
16
-
17
- ## Functionality
18
-
19
- This class works with the iubenda Cookie Law Solution and allows you to block the most common widgets and third-party cookies to comply with Cookie Law.
20
-
21
- The class is currently able to detect and automatically block the following scripts:
22
-
23
- * Google Analytics
24
- * Google Maps
25
- * Google AdSense
26
- * Google ReCaptcha
27
- * Google Site Search
28
- * Google Tag Manager
29
- * Google oAuth
30
- * Google+ widgets
31
- * Twitter widgets
32
- * Facebook widgets
33
- * Facebook Comments
34
- * YouTube
35
- * Vimeo
36
- * Linkedin widgets
37
- * ShareThis widgets
38
- * Instagram widgets
39
- * AddThis widgets
40
- * Pinterest widgets
41
- * PayPal widgets
42
- * Disqus
43
- * Optimizely
44
- * Neodata
45
- * Criteo
46
- * Outbrain
47
- * Headway
48
- * Codepen
49
- * Freshchat
50
- * Uservoice
51
- * AdRoll
52
- * Olark
53
- * Segment
54
- * Kissmetrics
55
- * Mixpanel
56
- * Pingdom
57
- * Bing
58
- * Elevio
59
-
60
-
61
- It also allows the manual blocking of all other resources without direct intervention on the actual scripts. Read more about the [prior blocking functionality here](https://www.iubenda.com/en/help/1229-cookie-law-solution-preventing-code-execution-that-could-install-cookies).
62
-
63
- * * *
64
-
65
- Here is an example of the PHP class integration:
66
- ```php
67
- function iubenda_system( $html, $type = 'page' ) {
68
- if ( empty( $html ) )
69
- return;
70
-
71
- require_once( 'iubenda.class.php' );
72
-
73
- // separator
74
- if ( ! iubendaParser::consent_given() && ! iubendaParser::bot_detected() ) {
75
- $iubenda = new iubendaParser( $html, array( 'type' => in_array( $type, array( 'page', 'faster' ), true ) ? $type : 'page' ) );
76
- $html = $iubenda->parse();
77
- }
78
-
79
- // finished
80
- return $html;
81
- }
82
- ```
83
-
84
- The `iubenda_system` method verifies if the page visitor consents to the use of cookies. If they have consented, the script returns the HTML provided as a parameter without taking any action such as parsing/replacing.
85
- Simply copy your method into the PHP document and then call it with the following syntax `iubenda_system("contenutohtml");` that will return the code.
86
-
87
- * Parsing/replacing the portions of code contained within `<!--IUB-COOKIE-BLOCK-START-->` and `<!--IUB-COOKIE-BLOCK-END-->`
88
- * Automatic parsing/replacing of iframe that contain defined src
89
- * Automatic parsing/replacing of scripts that contain defined src
90
-
91
- These operations take place in accordance with the rules explained in [this guide](https://www.iubenda.com/en/help/posts/1229). We suggest that you consult the posts relating to the alteration of script, img and iframe tags.
92
-
93
- ## Additional Help and docs
94
-
95
- * [Full Cookie Solution Documentation](https://www.iubenda.com/en/help/1205-technical-documentation-for-the-cookie-law-solution-banner-cookie-policy-and-consent-management)
96
- * [Prior Blocking Guide](https://www.iubenda.com/en/help/1229-cookie-law-solution-preventing-code-execution-that-could-install-cookies)
97
- * [Cookie Solution Feature Overview](https://www.iubenda.com/en/features#cookie-solution)
98
-
99
- ## Changelog
100
-
101
- ##### 4.1.0
102
- * New: Google AMP support
103
-
104
- ##### 4.0.0
105
- * New: Per-purpose script blocking support
106
- * New: Reject button support
107
-
108
- ##### 3.4.0
109
- * New: Introducing wildcard support for scripts and iframes
110
-
111
- ##### 3.3.1
112
- * Tweak: Improved Google Tag Manager script blocking
113
-
114
- ##### 3.3.0
115
- * Tweak: Simple HTML Dom PHP class update to 1.9
116
-
117
- ##### 3.2.0
118
- * New: Introducing a way to skip specific script parsing
119
-
120
- ##### 3.1.2
121
- * Tweak: Improved Youtube and Google Maps support
122
-
123
- ##### 3.1.1
124
- * Tweak: Update composer.json autoloader
125
-
126
- ##### 3.1.0
127
- * Tweak: Update and extend the list of blocked scripts including Google Site Search, Google oAuth, Linkedin widgets, PayPal widgets, Pinterest, AddThis, Disqus, Optimizely, Neodata, Criteo, Outbrain, Headway, Codepen, Freshchat, Uservoice
128
- , AdRoll, Olark, Segment, Kissmetrics, Mixpanel, Pingdom, Bing and Elevio
129
-
130
- ##### 3.0.0
131
- * Tweak: Update and unify iubenda parsing engine
132
-
133
- ### License
134
-
135
  This project is licensed under the GPl 3 license.
1
+ # Read Me
2
+
3
+ ***PHP class for the iubenda cookie law solution***
4
+
5
+ If you have European users you need to obtain and manage consent for the use of most cookies.
6
+ The iubenda Cookie Solution is an all-in-one approach developed by iubenda, that helps to make your website GDPR and Cookie Law compliant by integrating with your cookie policy, providing a compliant cookie banner and the blocking management of cookie scripts. The Cookie Solution also allows users to set advertising preferences on-site and within the solution, facilitated the recent-but-widely adopted IAB Europe Transparency & Consent [framework](https://www.iubenda.com/en/help/7440#aboutIAB).
7
+
8
+ [Read more about the Cookie Solution here](https://www.iubenda.com/en/features#cookie-solution).
9
+
10
+ * * *
11
+ #### This class allows you to scan a page in PHP for scripts and run the automatic blocking of scripts
12
+
13
+ *This is the class on which our WordPress and Joomla! and Drupal plugins are based and you can use it to build your own plugin independently for a platform other than those for which we have already developed a dedicated solution.*
14
+
15
+ * * *
16
+
17
+ ## Functionality
18
+
19
+ This class works with the iubenda Cookie Law Solution and allows you to block the most common widgets and third-party cookies to comply with Cookie Law.
20
+
21
+ The class is currently able to detect and automatically block the following scripts:
22
+
23
+ * Google Analytics
24
+ * Google Maps
25
+ * Google AdSense
26
+ * Google ReCaptcha
27
+ * Google Site Search
28
+ * Google Tag Manager
29
+ * Google oAuth
30
+ * Google+ widgets
31
+ * Twitter widgets
32
+ * Facebook widgets
33
+ * Facebook Comments
34
+ * YouTube
35
+ * Vimeo
36
+ * Linkedin widgets
37
+ * ShareThis widgets
38
+ * Instagram widgets
39
+ * AddThis widgets
40
+ * Pinterest widgets
41
+ * PayPal widgets
42
+ * Disqus
43
+ * Optimizely
44
+ * Neodata
45
+ * Criteo
46
+ * Outbrain
47
+ * Headway
48
+ * Codepen
49
+ * Freshchat
50
+ * Uservoice
51
+ * AdRoll
52
+ * Olark
53
+ * Segment
54
+ * Kissmetrics
55
+ * Mixpanel
56
+ * Pingdom
57
+ * Bing
58
+ * Elevio
59
+
60
+
61
+ It also allows the manual blocking of all other resources without direct intervention on the actual scripts. Read more about the [prior blocking functionality here](https://www.iubenda.com/en/help/1229-cookie-law-solution-preventing-code-execution-that-could-install-cookies).
62
+
63
+ * * *
64
+
65
+ Here is an example of the PHP class integration:
66
+ ```php
67
+ function iubenda_system( $html, $type = 'page' ) {
68
+ if ( empty( $html ) )
69
+ return;
70
+
71
+ require_once( 'iubenda.class.php' );
72
+
73
+ // separator
74
+ if ( ! iubendaParser::consent_given() && ! iubendaParser::bot_detected() ) {
75
+ $iubenda = new iubendaParser( $html, array( 'type' => in_array( $type, array( 'page', 'faster' ), true ) ? $type : 'page' ) );
76
+ $html = $iubenda->parse();
77
+ }
78
+
79
+ // finished
80
+ return $html;
81
+ }
82
+ ```
83
+
84
+ The `iubenda_system` method verifies if the page visitor consents to the use of cookies. If they have consented, the script returns the HTML provided as a parameter without taking any action such as parsing/replacing.
85
+ Simply copy your method into the PHP document and then call it with the following syntax `iubenda_system("contenutohtml");` that will return the code.
86
+
87
+ * Parsing/replacing the portions of code contained within `<!--IUB-COOKIE-BLOCK-START-->` and `<!--IUB-COOKIE-BLOCK-END-->`
88
+ * Automatic parsing/replacing of iframe that contain defined src
89
+ * Automatic parsing/replacing of scripts that contain defined src
90
+
91
+ These operations take place in accordance with the rules explained in [this guide](https://www.iubenda.com/en/help/posts/1229). We suggest that you consult the posts relating to the alteration of script, img and iframe tags.
92
+
93
+ ## Additional Help and docs
94
+
95
+ * [Full Cookie Solution Documentation](https://www.iubenda.com/en/help/1205-technical-documentation-for-the-cookie-law-solution-banner-cookie-policy-and-consent-management)
96
+ * [Prior Blocking Guide](https://www.iubenda.com/en/help/1229-cookie-law-solution-preventing-code-execution-that-could-install-cookies)
97
+ * [Cookie Solution Feature Overview](https://www.iubenda.com/en/features#cookie-solution)
98
+
99
+ ## Changelog
100
+
101
+ ##### 4.1.0
102
+ * New: Google AMP support
103
+
104
+ ##### 4.0.0
105
+ * New: Per-purpose script blocking support
106
+ * New: Reject button support
107
+
108
+ ##### 3.4.0
109
+ * New: Introducing wildcard support for scripts and iframes
110
+
111
+ ##### 3.3.1
112
+ * Tweak: Improved Google Tag Manager script blocking
113
+
114
+ ##### 3.3.0
115
+ * Tweak: Simple HTML Dom PHP class update to 1.9
116
+
117
+ ##### 3.2.0
118
+ * New: Introducing a way to skip specific script parsing
119
+
120
+ ##### 3.1.2
121
+ * Tweak: Improved Youtube and Google Maps support
122
+
123
+ ##### 3.1.1
124
+ * Tweak: Update composer.json autoloader
125
+
126
+ ##### 3.1.0
127
+ * Tweak: Update and extend the list of blocked scripts including Google Site Search, Google oAuth, Linkedin widgets, PayPal widgets, Pinterest, AddThis, Disqus, Optimizely, Neodata, Criteo, Outbrain, Headway, Codepen, Freshchat, Uservoice
128
+ , AdRoll, Olark, Segment, Kissmetrics, Mixpanel, Pingdom, Bing and Elevio
129
+
130
+ ##### 3.0.0
131
+ * Tweak: Update and unify iubenda parsing engine
132
+
133
+ ### License
134
+
135
  This project is licensed under the GPl 3 license.
iubenda-cookie-class/composer.json CHANGED
@@ -1,16 +1,16 @@
1
- {
2
- "name": "iubenda/iubenda-cookie-class",
3
- "type": "project",
4
- "description": "PHP class for the cookie law solution",
5
- "keywords": ["cookie","gdpr"],
6
- "homepage": "https://github.com/iubenda/iubenda-cookie-class",
7
- "license": "MIT",
8
- "require": {
9
- "php": ">=5.2.4"
10
- },
11
- "autoload": {
12
- "files": [
13
- "iubenda.class.php"
14
- ]
15
- }
16
  }
1
+ {
2
+ "name": "iubenda/iubenda-cookie-class",
3
+ "type": "project",
4
+ "description": "PHP class for the cookie law solution",
5
+ "keywords": ["cookie","gdpr"],
6
+ "homepage": "https://github.com/iubenda/iubenda-cookie-class",
7
+ "license": "MIT",
8
+ "require": {
9
+ "php": ">=5.2.4"
10
+ },
11
+ "autoload": {
12
+ "files": [
13
+ "iubenda.class.php"
14
+ ]
15
+ }
16
  }
iubenda-cookie-class/iubenda.class.page.php CHANGED
@@ -1,384 +1,384 @@
1
- <?php
2
- /**
3
- * iubenda.class.page.php
4
- *
5
- * @author iubenda s.r.l
6
- * @copyright 2018-2019, iubenda s.r.l
7
- * @license GNU/GPL
8
- * @version 1.0.3
9
- * @deprecated
10
- *
11
- * This program is free software: you can redistribute it and/or modify
12
- * it under the terms of the GNU General Public License as published by
13
- * the Free Software Foundation, either version 3 of the License, or
14
- * (at your option) any later version.
15
- *
16
- * This program is distributed in the hope that it will be useful,
17
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
- * GNU General Public License for more details.
20
- *
21
- * You should have received a copy of the GNU General Public License
22
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
23
- */
24
-
25
- class iubendaPage {
26
-
27
- // variables
28
- const IUB_REGEX_PATTERN = '/<!--\s*IUB_COOKIE_POLICY_START\s*-->(.*?)<!--\s*IUB_COOKIE_POLICY_END\s*-->/s';
29
- const IUB_REGEX_PATTERN_2 = '/<!--\s*IUB-COOKIE-BLOCK-START\s*-->(.*?)<!--\s*IUB-COOKIE-BLOCK-END\s*-->/s';
30
-
31
- public $auto_script_tags = array(
32
- 'platform.twitter.com/widgets.js',
33
- 'apis.google.com/js/plusone.js',
34
- 'apis.google.com/js/platform.js',
35
- 'connect.facebook.net',
36
- 'www.youtube.com/iframe_api',
37
- 'pagead2.googlesyndication.com/pagead/js/adsbygoogle.js',
38
- 'sharethis.com/button/buttons.js',
39
- 'addthis.com/js/',
40
- 'window.adsbygoogle'
41
- );
42
- public $auto_iframe_tags = array(
43
- 'youtube.com',
44
- 'platform.twitter.com',
45
- 'www.facebook.com/plugins/like.php',
46
- 'www.facebook.com/plugins/likebox.php',
47
- 'apis.google.com',
48
- 'www.google.com/maps/embed/',
49
- 'player.vimeo.com/video',
50
- 'maps.google.it/maps',
51
- 'www.google.com/maps/embed',
52
- 'window.adsbygoogle'
53
- );
54
- public $iub_comments_detected = array();
55
- public $iframe_detected = array();
56
- public $iframe_converted = array();
57
- public $scripts_detected = array();
58
- public $scripts_inline_detected = array();
59
- public $scripts_inline_converted = array();
60
- public $scripts_converted = array();
61
-
62
- /**
63
- * Construct: the whole HTML output of the page
64
- *
65
- * @param mixed $content_page
66
- */
67
- public function __construct( $content_page ) {
68
- $this->original_content_page = $content_page;
69
- $this->content_page = $content_page;
70
- }
71
-
72
- /**
73
- * Print iubenda banner, parameter: the script code of iubenda to print the banner
74
- *
75
- * @param string $banner
76
- * @return string
77
- */
78
- public function print_banner( $banner ) {
79
- return $banner .= "\n
80
- <script>
81
- var iCallback = function(){};
82
-
83
- if('callback' in _iub.csConfiguration) {
84
- if('onConsentGiven' in _iub.csConfiguration.callback) iCallback = _iub.csConfiguration.callback.onConsentGiven;
85
-
86
- _iub.csConfiguration.callback.onConsentGiven = function()
87
- {
88
- iCallback();
89
-
90
- /*
91
- * Separator
92
- */
93
-
94
- jQuery('noscript._no_script_iub').each(function (a, b) { var el = jQuery(b); el.after(el.html()); });
95
- };
96
- };
97
- </script>";
98
- }
99
-
100
- /**
101
- * Static, detect bot & crawler
102
- *
103
- * @return bool
104
- */
105
- static function bot_detected() {
106
- return ( isset( $_SERVER['HTTP_USER_AGENT'] ) && preg_match( '/bot|crawl|slurp|spider|google|yahoo/i', $_SERVER['HTTP_USER_AGENT'] ) );
107
- }
108
-
109
- /**
110
- * Static, utility function: Return true if the user has already given consent on the page
111
- *
112
- * @return boolean
113
- */
114
- static function consent_given() {
115
- foreach ( $_COOKIE as $key => $value ) {
116
- if ( iubendaPage::strpos_array( $key, array( '_iub_cs-s', '_iub_cs' ) ) ) {
117
- return true;
118
- }
119
- }
120
- return false;
121
- }
122
-
123
- /**
124
- * Static, utility function: strpos for array
125
- *
126
- * @param type $haystack
127
- * @param type $needle
128
- * @return boolean
129
- */
130
- static function strpos_array( $haystack, $needle ) {
131
- if ( is_array( $needle ) ) {
132
- foreach ( $needle as $need ) {
133
- if ( strpos( $haystack, $need ) !== false ) {
134
- return true;
135
- }
136
- }
137
- } else {
138
- if ( strpos( $haystack, $need ) !== false ) {
139
- return true;
140
- }
141
- }
142
- return false;
143
- }
144
-
145
- /**
146
- * Convert scripts, iframe and other code inside IUBENDAs comment in text/plain to not generate cookies
147
- *
148
- * @param mixed $html
149
- * @return mixed
150
- */
151
- public function create_tags( $html ) {
152
-
153
- $elements = $html->find( "*" );
154
- $js = '';
155
-
156
- if ( is_array( $elements ) ) {
157
- $count = count( $elements );
158
- for ( $j = 0; $j < $count; $j ++ ) {
159
- $e = $elements[$j];
160
- switch ( $e->tag ) {
161
- case 'script':
162
- $class = $e->class;
163
- $e->class = $class . ' _iub_cs_activate';
164
- $e->type = 'text/plain';
165
- $js .= $e->outertext;
166
- break;
167
-
168
- case 'iframe':
169
- $new_src = "//cdn.iubenda.com/cookie_solution/empty.html";
170
- $class = $e->class;
171
- $e->suppressedsrc = $e->src;
172
- $e->src = $new_src;
173
- $e->class = $class . ' _iub_cs_activate';
174
- $js .= $e->outertext;
175
- break;
176
-
177
- default:
178
- $js = $html;
179
- break;
180
- }
181
- }
182
- }
183
- return $js;
184
- }
185
-
186
- /**
187
- * Parse all IUBENDAs comment and convert the code inside with create_tags method
188
- */
189
- public function parse_iubenda_comments() {
190
- foreach ( array( 'IUB_REGEX_PATTERN', 'IUB_REGEX_PATTERN_2' ) as $pattern ) {
191
- preg_match_all( constant( 'self::' . $pattern ), $this->content_page, $scripts );
192
-
193
- if ( is_array( $scripts[1] ) ) {
194
- $count = count( $scripts[1] );
195
- $js_scripts = array();
196
- for ( $j = 0; $j < $count; $j ++ ) {
197
- $this->iub_comments_detected[] = $scripts[1][$j];
198
- $html = str_get_html( $scripts[1][$j], $lowercase = true, $forceTagsClosed = true, $stripRN = false );
199
- $js_scripts[] = $this->create_tags( $html );
200
- }
201
-
202
- if ( is_array( $scripts[1] ) && is_array( $js_scripts ) ) {
203
- if ( count( $scripts[1] ) >= 1 && count( $js_scripts ) >= 1 ) {
204
- $this->content_page = strtr( $this->content_page, array_combine( $scripts[1], $js_scripts ) );
205
- }
206
- }
207
- }
208
- }
209
- }
210
-
211
- /**
212
- * Parse automatically all the scripts in the page and converts it in text/plain
213
- * if src or the whole output has inside one of the elements in $auto_script_tags array
214
- */
215
- public function parse_scripts() {
216
- $html = str_get_html( $this->content_page, $lowercase = true, $forceTagsClosed = true, $stripRN = false );
217
-
218
- if ( is_object( $html ) ) {
219
- $scripts = $html->find( "script" );
220
- if ( is_array( $scripts ) ) {
221
- $count = count( $scripts );
222
- for ( $j = 0; $j < $count; $j ++ ) {
223
- $s = $scripts[$j];
224
- if ( ! empty( $s->innertext ) ) {
225
- $this->scripts_detected[] = $s->innertext;
226
- if ( iubendaPage::strpos_array( $s->innertext, $this->auto_script_tags ) !== false ) {
227
- $class = $s->class;
228
- $s->class = $class . ' _iub_cs_activate-inline';
229
- $s->type = 'text/plain';
230
- $this->scripts_converted[] = $s->innertext;
231
- }
232
- } else {
233
- $src = $s->src;
234
- if ( $src ) {
235
- $this->scripts_inline_detected[] = $src;
236
- if ( iubendaPage::strpos_array( $src, $this->auto_script_tags ) !== false ) {
237
- $class = $s->class;
238
- $s->class = $class . ' _iub_cs_activate';
239
- $s->type = 'text/plain';
240
- $this->scripts_inline_converted[] = $src;
241
- }
242
- }
243
- }
244
- }
245
- }
246
-
247
- // AdSense check by Peste Vasile Alexandru, AdSense here
248
- $ad_found = false;
249
-
250
- while ( preg_match( "#google_ad_client =(.*?);#i", $html ) ) {
251
- $ad_found = true;
252
- $ad_client = null;
253
- $ad_slot = null;
254
- $ad_width = null;
255
- $ad_height = null;
256
- $ad_block = null;
257
-
258
- preg_match( "#google_ad_client =(.*?);#i", $html, $ad_client );
259
- preg_match( "#google_ad_slot =(.*?);#i", $html, $ad_slot );
260
- preg_match( "#google_ad_width =(.*?);#i", $html, $ad_width );
261
- preg_match( "#google_ad_height =(.*?);#i", $html, $ad_height );
262
-
263
- $html = preg_replace( "#google_ad_client =(.*?);#i", "", $html, 1 );
264
- $html = preg_replace( "#google_ad_slot =(.*?);#i", "", $html, 1 );
265
- $html = preg_replace( "#google_ad_width =(.*?);#i", "", $html, 1 );
266
- $html = preg_replace( "#google_ad_height =(.*?);#i", "", $html, 1 );
267
-
268
- $ad_client = trim( $ad_client[1] );
269
- $ad_slot = trim( $ad_slot[1] );
270
- $ad_width = trim( $ad_width[1] );
271
- $ad_height = trim( $ad_height[1] );
272
-
273
- $ad_class = 'class="_iub_cs_activate_google_ads"';
274
- $ad_style = 'style="width:' . $ad_width . 'px; height:' . $ad_height . 'px;"';
275
-
276
- $ad_client = 'data-client=' . $ad_client;
277
- $ad_slot = 'data-slot=' . $ad_slot;
278
- $ad_width = 'data-width="' . $ad_width . '"';
279
- $ad_height = 'data-height="' . $ad_height . '"';
280
-
281
- $ad_block = "<div $ad_style $ad_class $ad_width $ad_height $ad_slot $ad_client></div>";
282
-
283
- $html = preg_replace( '#(<[^>]+) src="//pagead2.googlesyndication.com/pagead/show_ads.js"(.*?)</script>#i', $ad_block, $html, 1 );
284
- }
285
-
286
- if ( $ad_found ) {
287
- $adsense_callback = "
288
- <script>
289
- function iubenda_adsense_unblock(){
290
- var t = 1;
291
- jQuery('._iub_cs_activate_google_ads').each(function() {
292
- var banner = jQuery(this);
293
- setTimeout(function(){
294
- var client = banner.data('client');
295
- var slot = banner.data('slot');
296
- var width = banner.data('width');
297
- var height = banner.data('height');
298
- var adsense_script = '<scr'+'ipt>'
299
- + 'google_ad_client = " . chr( 34 ) . "'+client+'" . chr( 34 ) . ";'
300
- + 'google_ad_slot = '+slot+';'
301
- + 'google_ad_width = '+width+';'
302
- + 'google_ad_height = '+height+';'
303
- + '</scr'+'ipt>';
304
- var script = document.createElement('script');
305
- var ads = document.createElement('ads');
306
- var w = document.write;
307
- script.setAttribute('type', 'text/javascript');
308
- script.setAttribute('src', 'http://pagead2.googlesyndication.com/pagead/show_ads.js');
309
- document.write = (function(params) {
310
- ads.innerHTML = params;
311
- document.write = w;
312
- });
313
- banner.html(adsense_script).append(ads).append(script);
314
- }, t);
315
- t += 300;
316
- });
317
- }
318
- if('callback' in _iub.csConfiguration) {
319
- _iub.csConfiguration.callback.onConsentGiven = iubenda_adsense_unblock;
320
- }
321
- else
322
- {
323
- _iub.csConfiguration.callback = {};
324
-
325
- _iub.csConfiguration.callback.onConsentGiven = iubenda_adsense_unblock;
326
- }
327
- </script>
328
- ";
329
-
330
- $html = str_replace( "</body>", $adsense_callback . "</body>", $html );
331
- }
332
-
333
- $this->content_page = $html;
334
- }
335
- }
336
-
337
- /**
338
- * Parse automatically all the iframe in the page and change the src to suppressedsrc
339
- * if src has inside one of the elements in $auto_iframe_tags array
340
- */
341
- public function parse_iframe() {
342
- $html = str_get_html( $this->content_page, $lowercase = true, $forceTagsClosed = true, $stripRN = false );
343
-
344
- if ( is_object( $html ) ) {
345
- $iframes = $html->find( "iframe" );
346
- if ( is_array( $iframes ) ) {
347
- $count = count( $iframes );
348
- for ( $j = 0; $j < $count; $j ++ ) {
349
- $i = $iframes[$j];
350
- $src = $i->src;
351
- $this->iframe_detected[] = $src;
352
- if ( iubendaPage::strpos_array( $src, $this->auto_iframe_tags ) !== false ) {
353
- $new_src = "//cdn.iubenda.com/cookie_solution/empty.html";
354
- $class = $i->class;
355
- $i->suppressedsrc = $src;
356
- $i->src = $new_src;
357
- $i->class = $class . ' _iub_cs_activate';
358
- $this->iframe_converted[] = $src;
359
- }
360
- }
361
- }
362
- $this->content_page = $html;
363
- }
364
- }
365
-
366
- /**
367
- * Call three methods to parse the page, iubendas comment, scripts + iframe
368
- */
369
- public function parse() {
370
- $this->parse_iubenda_comments();
371
- $this->parse_scripts();
372
- $this->parse_iframe();
373
- }
374
-
375
- /**
376
- * Return the final page to output
377
- *
378
- * @return mixed
379
- */
380
- public function get_converted_page() {
381
- return $this->content_page;
382
- }
383
-
384
  }
1
+ <?php
2
+ /**
3
+ * iubenda.class.page.php
4
+ *
5
+ * @author iubenda s.r.l
6
+ * @copyright 2018-2019, iubenda s.r.l
7
+ * @license GNU/GPL
8
+ * @version 1.0.3
9
+ * @deprecated
10
+ *
11
+ * This program is free software: you can redistribute it and/or modify
12
+ * it under the terms of the GNU General Public License as published by
13
+ * the Free Software Foundation, either version 3 of the License, or
14
+ * (at your option) any later version.
15
+ *
16
+ * This program is distributed in the hope that it will be useful,
17
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
+ * GNU General Public License for more details.
20
+ *
21
+ * You should have received a copy of the GNU General Public License
22
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
23
+ */
24
+
25
+ class iubendaPage {
26
+
27
+ // variables
28
+ const IUB_REGEX_PATTERN = '/<!--\s*IUB_COOKIE_POLICY_START\s*-->(.*?)<!--\s*IUB_COOKIE_POLICY_END\s*-->/s';
29
+ const IUB_REGEX_PATTERN_2 = '/<!--\s*IUB-COOKIE-BLOCK-START\s*-->(.*?)<!--\s*IUB-COOKIE-BLOCK-END\s*-->/s';
30
+
31
+ public $auto_script_tags = array(
32
+ 'platform.twitter.com/widgets.js',
33
+ 'apis.google.com/js/plusone.js',
34
+ 'apis.google.com/js/platform.js',
35
+ 'connect.facebook.net',
36
+ 'www.youtube.com/iframe_api',
37
+ 'pagead2.googlesyndication.com/pagead/js/adsbygoogle.js',
38
+ 'sharethis.com/button/buttons.js',
39
+ 'addthis.com/js/',
40
+ 'window.adsbygoogle'
41
+ );
42
+ public $auto_iframe_tags = array(
43
+ 'youtube.com',
44
+ 'platform.twitter.com',
45
+ 'www.facebook.com/plugins/like.php',
46
+ 'www.facebook.com/plugins/likebox.php',
47
+ 'apis.google.com',
48
+ 'www.google.com/maps/embed/',
49
+ 'player.vimeo.com/video',
50
+ 'maps.google.it/maps',
51
+ 'www.google.com/maps/embed',
52
+ 'window.adsbygoogle'
53
+ );
54
+ public $iub_comments_detected = array();
55
+ public $iframe_detected = array();
56
+ public $iframe_converted = array();
57
+ public $scripts_detected = array();
58
+ public $scripts_inline_detected = array();
59
+ public $scripts_inline_converted = array();
60
+ public $scripts_converted = array();
61
+
62
+ /**
63
+ * Construct: the whole HTML output of the page
64
+ *
65
+ * @param mixed $content_page
66
+ */
67
+ public function __construct( $content_page ) {
68
+ $this->original_content_page = $content_page;
69
+ $this->content_page = $content_page;
70
+ }
71
+
72
+ /**
73
+ * Print iubenda banner, parameter: the script code of iubenda to print the banner
74
+ *
75
+ * @param string $banner
76
+ * @return string
77
+ */
78
+ public function print_banner( $banner ) {
79
+ return $banner .= "\n
80
+ <script>
81
+ var iCallback = function(){};
82
+
83
+ if('callback' in _iub.csConfiguration) {
84
+ if('onConsentGiven' in _iub.csConfiguration.callback) iCallback = _iub.csConfiguration.callback.onConsentGiven;
85
+
86
+ _iub.csConfiguration.callback.onConsentGiven = function()
87
+ {
88
+ iCallback();
89
+
90
+ /*
91
+ * Separator
92
+ */
93
+
94
+ jQuery('noscript._no_script_iub').each(function (a, b) { var el = jQuery(b); el.after(el.html()); });
95
+ };
96
+ };
97
+ </script>";
98
+ }
99
+
100
+ /**
101
+ * Static, detect bot & crawler
102
+ *
103
+ * @return bool
104
+ */
105
+ static function bot_detected() {
106
+ return ( isset( $_SERVER['HTTP_USER_AGENT'] ) && preg_match( '/bot|crawl|slurp|spider|google|yahoo/i', $_SERVER['HTTP_USER_AGENT'] ) );
107
+ }
108
+
109
+ /**
110
+ * Static, utility function: Return true if the user has already given consent on the page
111
+ *
112
+ * @return boolean
113
+ */
114
+ static function consent_given() {
115
+ foreach ( $_COOKIE as $key => $value ) {
116
+ if ( iubendaPage::strpos_array( $key, array( '_iub_cs-s', '_iub_cs' ) ) ) {
117
+ return true;
118
+ }
119
+ }
120
+ return false;
121
+ }
122
+
123
+ /**
124
+ * Static, utility function: strpos for array
125
+ *
126
+ * @param type $haystack
127
+ * @param type $needle
128
+ * @return boolean
129
+ */
130
+ static function strpos_array( $haystack, $needle ) {
131
+ if ( is_array( $needle ) ) {
132
+ foreach ( $needle as $need ) {
133
+ if ( strpos( $haystack, $need ) !== false ) {
134
+ return true;
135
+ }
136
+ }
137
+ } else {
138
+ if ( strpos( $haystack, $need ) !== false ) {
139
+ return true;
140
+ }
141
+ }
142
+ return false;
143
+ }
144
+
145
+ /**
146
+ * Convert scripts, iframe and other code inside IUBENDAs comment in text/plain to not generate cookies
147
+ *
148
+ * @param mixed $html
149
+ * @return mixed
150
+ */
151
+ public function create_tags( $html ) {
152
+
153
+ $elements = $html->find( "*" );
154
+ $js = '';
155
+
156
+ if ( is_array( $elements ) ) {
157
+ $count = count( $elements );
158
+ for ( $j = 0; $j < $count; $j ++ ) {
159
+ $e = $elements[$j];
160
+ switch ( $e->tag ) {
161
+ case 'script':
162
+ $class = $e->class;
163
+ $e->class = $class . ' _iub_cs_activate';
164
+ $e->type = 'text/plain';
165
+ $js .= $e->outertext;
166
+ break;
167
+
168
+ case 'iframe':
169
+ $new_src = "//cdn.iubenda.com/cookie_solution/empty.html";
170
+ $class = $e->class;
171
+ $e->suppressedsrc = $e->src;
172
+ $e->src = $new_src;
173
+ $e->class = $class . ' _iub_cs_activate';
174
+ $js .= $e->outertext;
175
+ break;
176
+
177
+ default:
178
+ $js = $html;
179
+ break;
180
+ }
181
+ }
182
+ }
183
+ return $js;
184
+ }
185
+
186
+ /**
187
+ * Parse all IUBENDAs comment and convert the code inside with create_tags method
188
+ */
189
+ public function parse_iubenda_comments() {
190
+ foreach ( array( 'IUB_REGEX_PATTERN', 'IUB_REGEX_PATTERN_2' ) as $pattern ) {
191
+ preg_match_all( constant( 'self::' . $pattern ), $this->content_page, $scripts );
192
+
193
+ if ( is_array( $scripts[1] ) ) {
194
+ $count = count( $scripts[1] );
195
+ $js_scripts = array();
196
+ for ( $j = 0; $j < $count; $j ++ ) {
197
+ $this->iub_comments_detected[] = $scripts[1][$j];
198
+ $html = str_get_html( $scripts[1][$j], $lowercase = true, $forceTagsClosed = true, $stripRN = false );
199
+ $js_scripts[] = $this->create_tags( $html );
200
+ }
201
+
202
+ if ( is_array( $scripts[1] ) && is_array( $js_scripts ) ) {
203
+ if ( count( $scripts[1] ) >= 1 && count( $js_scripts ) >= 1 ) {
204
+ $this->content_page = strtr( $this->content_page, array_combine( $scripts[1], $js_scripts ) );
205
+ }
206
+ }
207
+ }
208
+ }
209
+ }
210
+
211
+ /**
212
+ * Parse automatically all the scripts in the page and converts it in text/plain
213
+ * if src or the whole output has inside one of the elements in $auto_script_tags array
214
+ */
215
+ public function parse_scripts() {
216
+ $html = str_get_html( $this->content_page, $lowercase = true, $forceTagsClosed = true, $stripRN = false );
217
+
218
+ if ( is_object( $html ) ) {
219
+ $scripts = $html->find( "script" );
220
+ if ( is_array( $scripts ) ) {
221
+ $count = count( $scripts );
222
+ for ( $j = 0; $j < $count; $j ++ ) {
223
+ $s = $scripts[$j];
224
+ if ( ! empty( $s->innertext ) ) {
225
+ $this->scripts_detected[] = $s->innertext;
226
+ if ( iubendaPage::strpos_array( $s->innertext, $this->auto_script_tags ) !== false ) {
227
+ $class = $s->class;
228
+ $s->class = $class . ' _iub_cs_activate-inline';
229
+ $s->type = 'text/plain';
230
+ $this->scripts_converted[] = $s->innertext;
231
+ }
232
+ } else {
233
+ $src = $s->src;
234
+ if ( $src ) {
235
+ $this->scripts_inline_detected[] = $src;
236
+ if ( iubendaPage::strpos_array( $src, $this->auto_script_tags ) !== false ) {
237
+ $class = $s->class;
238
+ $s->class = $class . ' _iub_cs_activate';
239
+ $s->type = 'text/plain';
240
+ $this->scripts_inline_converted[] = $src;
241
+ }
242
+ }
243
+ }
244
+ }
245
+ }
246
+
247
+ // AdSense check by Peste Vasile Alexandru, AdSense here
248
+ $ad_found = false;
249
+
250
+ while ( preg_match( "#google_ad_client =(.*?);#i", $html ) ) {
251
+ $ad_found = true;
252
+ $ad_client = null;
253
+ $ad_slot = null;
254
+ $ad_width = null;
255
+ $ad_height = null;
256
+ $ad_block = null;
257
+
258
+ preg_match( "#google_ad_client =(.*?);#i", $html, $ad_client );
259
+ preg_match( "#google_ad_slot =(.*?);#i", $html, $ad_slot );
260
+ preg_match( "#google_ad_width =(.*?);#i", $html, $ad_width );
261
+ preg_match( "#google_ad_height =(.*?);#i", $html, $ad_height );
262
+
263
+ $html = preg_replace( "#google_ad_client =(.*?);#i", "", $html, 1 );
264
+ $html = preg_replace( "#google_ad_slot =(.*?);#i", "", $html, 1 );
265
+ $html = preg_replace( "#google_ad_width =(.*?);#i", "", $html, 1 );
266
+ $html = preg_replace( "#google_ad_height =(.*?);#i", "", $html, 1 );
267
+
268
+ $ad_client = trim( $ad_client[1] );
269
+ $ad_slot = trim( $ad_slot[1] );
270
+ $ad_width = trim( $ad_width[1] );
271
+ $ad_height = trim( $ad_height[1] );
272
+
273
+ $ad_class = 'class="_iub_cs_activate_google_ads"';
274
+ $ad_style = 'style="width:' . $ad_width . 'px; height:' . $ad_height . 'px;"';
275
+
276
+ $ad_client = 'data-client=' . $ad_client;
277
+ $ad_slot = 'data-slot=' . $ad_slot;
278
+ $ad_width = 'data-width="' . $ad_width . '"';
279
+ $ad_height = 'data-height="' . $ad_height . '"';
280
+
281
+ $ad_block = "<div $ad_style $ad_class $ad_width $ad_height $ad_slot $ad_client></div>";
282
+
283
+ $html = preg_replace( '#(<[^>]+) src="//pagead2.googlesyndication.com/pagead/show_ads.js"(.*?)</script>#i', $ad_block, $html, 1 );
284
+ }
285
+
286
+ if ( $ad_found ) {
287
+ $adsense_callback = "
288
+ <script>
289
+ function iubenda_adsense_unblock(){
290
+ var t = 1;
291
+ jQuery('._iub_cs_activate_google_ads').each(function() {
292
+ var banner = jQuery(this);
293
+ setTimeout(function(){
294
+ var client = banner.data('client');
295
+ var slot = banner.data('slot');
296
+ var width = banner.data('width');
297
+ var height = banner.data('height');
298
+ var adsense_script = '<scr'+'ipt>'
299
+ + 'google_ad_client = " . chr( 34 ) . "'+client+'" . chr( 34 ) . ";'
300
+ + 'google_ad_slot = '+slot+';'
301
+ + 'google_ad_width = '+width+';'
302
+ + 'google_ad_height = '+height+';'
303
+ + '</scr'+'ipt>';
304
+ var script = document.createElement('script');
305
+ var ads = document.createElement('ads');
306
+ var w = document.write;
307
+ script.setAttribute('type', 'text/javascript');
308
+ script.setAttribute('src', 'http://pagead2.googlesyndication.com/pagead/show_ads.js');
309
+ document.write = (function(params) {
310
+ ads.innerHTML = params;
311
+ document.write = w;
312
+ });
313
+ banner.html(adsense_script).append(ads).append(script);
314
+ }, t);
315
+ t += 300;
316
+ });
317
+ }
318
+ if('callback' in _iub.csConfiguration) {
319
+ _iub.csConfiguration.callback.onConsentGiven = iubenda_adsense_unblock;
320
+ }
321
+ else
322
+ {
323
+ _iub.csConfiguration.callback = {};
324
+
325
+ _iub.csConfiguration.callback.onConsentGiven = iubenda_adsense_unblock;
326
+ }
327
+ </script>
328
+ ";
329
+
330
+ $html = str_replace( "</body>", $adsense_callback . "</body>", $html );
331
+ }
332
+
333
+ $this->content_page = $html;
334
+ }
335
+ }
336
+
337
+ /**
338
+ * Parse automatically all the iframe in the page and change the src to suppressedsrc
339
+ * if src has inside one of the elements in $auto_iframe_tags array
340
+ */
341
+ public function parse_iframe() {
342
+ $html = str_get_html( $this->content_page, $lowercase = true, $forceTagsClosed = true, $stripRN = false );
343
+
344
+ if ( is_object( $html ) ) {
345
+ $iframes = $html->find( "iframe" );
346
+ if ( is_array( $iframes ) ) {
347
+ $count = count( $iframes );
348
+ for ( $j = 0; $j < $count; $j ++ ) {
349
+ $i = $iframes[$j];
350
+ $src = $i->src;
351
+ $this->iframe_detected[] = $src;
352
+ if ( iubendaPage::strpos_array( $src, $this->auto_iframe_tags ) !== false ) {
353
+ $new_src = "//cdn.iubenda.com/cookie_solution/empty.html";
354
+ $class = $i->class;
355
+ $i->suppressedsrc = $src;
356
+ $i->src = $new_src;
357
+ $i->class = $class . ' _iub_cs_activate';
358
+ $this->iframe_converted[] = $src;
359
+ }
360
+ }
361
+ }
362
+ $this->content_page = $html;
363
+ }
364
+ }
365
+
366
+ /**
367
+ * Call three methods to parse the page, iubendas comment, scripts + iframe
368
+ */
369
+ public function parse() {
370
+ $this->parse_iubenda_comments();
371
+ $this->parse_scripts();
372
+ $this->parse_iframe();
373
+ }
374
+
375
+ /**
376
+ * Return the final page to output
377
+ *
378
+ * @return mixed
379
+ */
380
+ public function get_converted_page() {
381
+ return $this->content_page;
382
+ }
383
+
384
  }
iubenda-cookie-class/iubenda.class.php CHANGED
@@ -1,13 +1,13 @@
1
  <?php
2
  /**
3
  * iubenda.class.php
4
- *
5
  * @author iubenda s.r.l
6
  * @copyright 2018-2020, iubenda s.r.l
7
  * @license GNU/GPL
8
  * @version 4.1.0
9
  * @deprecated
10
- *
11
  * This program is free software: you can redistribute it and/or modify
12
  * it under the terms of the GNU General Public License as published by
13
  * the Free Software Foundation, either version 3 of the License, or
@@ -35,10 +35,10 @@ class iubendaParser {
35
 
36
  // iframes
37
  public $auto_iframe_tags = array();
38
-
39
  // purposes
40
  public $purposes = array();
41
-
42
  // per-purpose scripts
43
  public $script_tags = array(
44
  // Strictly necessary
@@ -71,12 +71,12 @@ class iubendaParser {
71
  'platform.linkedin.com/in.js',
72
  'pinterest.com/js/pinit.js',
73
  'codepen.io',
 
74
  'bat.bing.com'
75
  ),
76
  // Analytics
77
  4 => array(
78
  'sharethis.com/button/buttons.js',
79
- 'addthis.com/js/',
80
  'scorecardresearch.com/beacon.js',
81
  'neodatagroup.com',
82
  'lp4.io',
@@ -104,7 +104,7 @@ class iubendaParser {
104
  'scdn.cxense.com'
105
  )
106
  );
107
-
108
  // per-purpose iframes
109
  public $iframe_tags = array(
110
  // Strictly necessary
@@ -156,14 +156,14 @@ class iubendaParser {
156
 
157
  /**
158
  * Construct: the whole HTML output of the page
159
- *
160
  * @param mixed $content_page
161
  * @param array $args
162
  */
163
  public function __construct( $content_page = '', $args = array() ) {
164
  // valid type?
165
  $this->type = ! empty( $args['type'] ) && in_array( $args['type'], array( 'page', 'faster' ), true ) ? $args['type'] : 'page';
166
-
167
  // amp support>
168
  $this->amp = (bool) ( isset( $args['amp'] ) && $args['amp'] === true );
169
 
@@ -190,7 +190,7 @@ class iubendaParser {
190
  $this->auto_script_tags = array_merge( $this->auto_script_tags, $args['scripts'][0] );
191
  unset( $args['scripts'][0] );
192
  }
193
-
194
  $this->script_tags = $this->array_merge_custom( $this->script_tags, $args['scripts'] );
195
  }
196
  }
@@ -207,7 +207,7 @@ class iubendaParser {
207
  $this->auto_iframe_tags = array_merge( $this->auto_iframe_tags, $args['iframes'][0] );
208
  unset( $args['iframes'][0] );
209
  }
210
-
211
  $this->iframe_tags = $this->array_merge_custom( $this->iframe_tags, $args['iframes'] );
212
  }
213
  }
@@ -221,7 +221,7 @@ class iubendaParser {
221
 
222
  /**
223
  * Static, detect bot & crawler
224
- *
225
  * @return bool
226
  */
227
  static function bot_detected() {
@@ -230,22 +230,22 @@ class iubendaParser {
230
 
231
  /**
232
  * Static, utility function: Return true if the user has already given consent on the page
233
- *
234
  * @return boolean
235
  */
236
  static function consent_given() {
237
  $consent_given = false;
238
-
239
  foreach ( $_COOKIE as $key => $value ) {
240
  $found = self::strpos_array( $key, array( '_iub_cs-s', '_iub_cs' ) );
241
-
242
  if ( $found !== false ) {
243
  $consent_data = json_decode( stripslashes( $value ), true );
244
-
245
  // read cookie value if given
246
  if ( isset( $consent_data['consent'] ) && $consent_data['consent'] == true )
247
  $consent_given = true;
248
-
249
  // read purposes if given
250
  if ( ! empty( $consent_data['purposes'] ) && is_array( $consent_data['purposes'] ) ) {
251
  // all purposes accepted, consent given
@@ -260,49 +260,49 @@ class iubendaParser {
260
 
261
  /**
262
  * Get user accepted purposes.
263
- *
264
  * @return array
265
  */
266
  static function get_purposes() {
267
  $purposes = array();
268
-
269
  if ( ! empty( $_COOKIE ) ) {
270
  foreach ( $_COOKIE as $key => $value ) {
271
  $found = self::strpos_array( $key, array( '_iub_cs-s', '_iub_cs' ) );
272
-
273
  if ( $found !== false ) {
274
  $consent_data = json_decode( $value, true );
275
-
276
  // read purposes if given
277
- if ( ! empty( $consent_data['purposes'] ) && is_array( $consent_data['purposes'] ) )
278
  $purposes = $consent_data['purposes'];
279
  }
280
  }
281
  }
282
-
283
  return $purposes;
284
  }
285
-
286
  /**
287
  * Get script tags to be blocked.
288
- *
289
  * @return array
290
  */
291
  private function get_script_tags() {
292
  $tags = $this->auto_script_tags;
293
-
294
  foreach ( $this->script_tags as $purpose_id => $tags_list ) {
295
  // empty tags list, go to another
296
  if ( empty( $tags_list ) )
297
  continue;
298
-
299
  // purposes available, filter per purpose
300
  if ( ! empty( $this->purposes ) ) {
301
  // don't block scripts unavailable in the user purposes
302
  // if ( array_key_exists( $purpose_id, $this->purposes ) && $this->purposes[$purpose_id] == false ) {
303
-
304
  // block scripts unavailable in the user purposes
305
- if ( ! isset( $this->purposes[$purpose_id] ) || $this->purposes[$purpose_id] == false ) {
306
  foreach ( $tags_list as $tag ) {
307
  $tags[] = $tag;
308
  }
@@ -314,30 +314,30 @@ class iubendaParser {
314
  }
315
  }
316
  }
317
-
318
  return $tags;
319
  }
320
-
321
  /**
322
  * Get iframe tags to be blocked.
323
- *
324
  * @return array
325
  */
326
  private function get_iframe_tags() {
327
  $tags = $this->auto_iframe_tags;
328
-
329
  foreach ( $this->iframe_tags as $purpose_id => $tags_list ) {
330
  // empty tags list, go to another
331
  if ( empty( $tags_list ) )
332
  continue;
333
-
334
  // purposes available, filter per purpose
335
  if ( ! empty( $this->purposes ) ) {
336
  // don't block iframes unavailable in the user purposes
337
  // if ( array_key_exists( $purpose_id, $this->purposes ) && $this->purposes[$purpose_id] == false ) {
338
-
339
  // block iframes unavailable in the user purposes
340
- if ( ! isset( $this->purposes[$purpose_id] ) && $this->purposes[$purpose_id] == false ) {
341
  foreach ( $tags_list as $tag ) {
342
  $tags[] = $tag;
343
  }
@@ -349,13 +349,13 @@ class iubendaParser {
349
  }
350
  }
351
  }
352
-
353
  return $tags;
354
  }
355
 
356
  /**
357
  * Convert scripts, iframe and other code inside IUBENDAs comment in text/plain to not generate cookies
358
- *
359
  * @param mixed $content
360
  * @return mixed
361
  */
@@ -373,7 +373,7 @@ class iubendaParser {
373
  case 'script':
374
  if ( $args['pattern'] === 'IUB_REGEX_PURPOSE_PATTERN' )
375
  $e->{'data-iub-purposes'} = $args['number'];
376
-
377
  // AMP support
378
  if ( $this->amp )
379
  $e->{'data-block-on-consent'} = '_till_accepted';
@@ -387,7 +387,7 @@ class iubendaParser {
387
  case 'iframe':
388
  if ( $args['pattern'] === 'IUB_REGEX_PURPOSE_PATTERN' )
389
  $e->{'data-iub-purposes'} = $args['number'];
390
-
391
  // AMP support
392
  if ( $this->amp )
393
  $e->{'data-block-on-consent'} = '_till_accepted';
@@ -412,7 +412,7 @@ class iubendaParser {
412
 
413
  /**
414
  * Skip scripts and iframes inside IUBENDAs comments.
415
- *
416
  * @param string $content
417
  * @return string
418
  */
@@ -445,7 +445,7 @@ class iubendaParser {
445
  }
446
 
447
  /**
448
- * Parse automatically all the scripts in the page and converts it in text/plain
449
  * if src or the whole output has inside one of the elements in $auto_script_tags array
450
  *
451
  * @return void
@@ -455,7 +455,7 @@ class iubendaParser {
455
  case 'page':
456
  // get page contents
457
  $html = str_get_html( $this->content_page, true, true, false );
458
-
459
  if ( is_object( $html ) ) {
460
  // get scripts
461
  $scripts = $html->find( 'script' );
@@ -485,7 +485,7 @@ class iubendaParser {
485
 
486
  if ( ! empty( $s->innertext ) ) {
487
  $this->scripts_inline_detected[] = $s->innertext;
488
-
489
  $found = self::strpos_array( $s->innertext, $this->auto_script_tags );
490
 
491
  if ( $found !== false ) {
@@ -499,21 +499,21 @@ class iubendaParser {
499
 
500
  if ( $src ) {
501
  $this->scripts_detected[] = $src;
502
-
503
  $found = self::strpos_array( $src, $this->auto_script_tags );
504
 
505
  if ( $found !== false ) {
506
  $class = $s->class;
507
  $s->class = $class . ' ' . $this->iub_class;
508
  $s->type = 'text/plain';
509
-
510
  // add data-iub-purposes attribute
511
  $s->{'data-iub-purposes'} = $this->recursive_array_search( $found, $this->script_tags );
512
-
513
  // AMP support
514
  if ( $this->amp )
515
  $s->{'data-block-on-consent'} = '_till_accepted';
516
-
517
  $this->scripts_converted[] = $src;
518
  }
519
  }
@@ -660,17 +660,17 @@ class iubendaParser {
660
  // add inline script as detected
661
  if ( ! empty( $script->nodeValue ) )
662
  $this->scripts_inline_detected[] = $script->nodeValue;
663
-
664
  $found = self::strpos_array( $src, $script_tags );
665
  $found_inline = self::strpos_array( $script->nodeValue, $script_tags );
666
 
667
  if ( $found !== false ) {
668
  $script->setAttribute( 'type', 'text/plain' );
669
  $script->setAttribute( 'class', $script->getAttribute( 'class' ) . ' ' . $class );
670
-
671
  // add data-iub-purposes attribute
672
  $script->setAttribute( 'data-iub-purposes', $this->recursive_array_search( $found, $this->script_tags ) );
673
-
674
  // AMP support
675
  if ( $this->amp )
676
  $script->setAttribute( 'data-block-on-consent', '_till_accepted' );
@@ -680,7 +680,7 @@ class iubendaParser {
680
  } elseif ( $found_inline !== false ) {
681
  $script->setAttribute( 'type', 'text/plain' );
682
  $script->setAttribute( 'class', $script->getAttribute( 'class' ) . ' ' . $class_inline );
683
-
684
  // AMP support
685
  if ( $this->amp )
686
  $script->setAttribute( 'data-block-on-consent', '_till_accepted' );
@@ -737,22 +737,22 @@ class iubendaParser {
737
 
738
  $src = $i->src;
739
  $this->iframes_detected[] = $src;
740
-
741
  $found = self::strpos_array( $src, $this->auto_iframe_tags );
742
-
743
  if ( $found !== false ) {
744
  $class = $i->class;
745
  $i->suppressedsrc = $src;
746
  $i->src = $this->iub_empty;
747
  $i->class = $class . ' ' . $this->iub_class;
748
-
749
  // add data-iub-purposes attribute
750
  $i->{'data-iub-purposes'} = $this->recursive_array_search( $found, $this->iframe_tags );
751
-
752
  // AMP support
753
  if ( $this->amp )
754
  $i->{'data-block-on-consent'} = '_till_accepted';
755
-
756
  $this->iframes_converted[] = $src;
757
  }
758
  }
@@ -803,17 +803,17 @@ class iubendaParser {
803
 
804
  // add iframe as detected
805
  $this->iframes_detected[] = $src;
806
-
807
  $found = self::strpos_array( $src, $iframe_tags );
808
 
809
  if ( $found !== false ) {
810
  $iframe->setAttribute( 'src', $empty );
811
  $iframe->setAttribute( 'suppressedsrc', $src );
812
  $iframe->setAttribute( 'class', $iframe_class . ' ' . $class );
813
-
814
  // per purpose, add data-iub-purposes attribute
815
  $iframe->setAttribute( 'data-iub-purposes', $this->recursive_array_search( $found, $this->iframe_tags ) );
816
-
817
  // AMP support
818
  if ( $this->amp )
819
  $iframe->setAttribute( 'data-block-on-consent', '_till_accepted' );
@@ -837,7 +837,7 @@ class iubendaParser {
837
 
838
  /**
839
  * Parse all IUBENDAs comments.
840
- *
841
  * @return void
842
  */
843
  public function parse_comments() {
@@ -919,7 +919,7 @@ class iubendaParser {
919
 
920
  /**
921
  * Return the final page to output
922
- *
923
  * @return mixed
924
  */
925
  public function get_converted_page() {
@@ -928,7 +928,7 @@ class iubendaParser {
928
 
929
  /**
930
  * Print iubenda banner, parameter: the script code of iubenda to print the banner
931
- *
932
  * @param string $banner
933
  * @return string
934
  */
@@ -949,10 +949,10 @@ class iubendaParser {
949
  };
950
  </script>";
951
  }
952
-
953
  /**
954
  * Static, utility function: strpos for array wilth wildcard support
955
- *
956
  * @param type $haystack
957
  * @param type $needle
958
  * @return boolean
@@ -960,7 +960,7 @@ class iubendaParser {
960
  static function strpos_array( $haystack, $needle ) {
961
  if ( empty( $haystack ) || empty( $needle ) )
962
  return false;
963
-
964
  $needle = ! is_array( $needle ) ? array( $needle ) : $needle;
965
 
966
  foreach ( $needle as $need ) {
@@ -970,11 +970,11 @@ class iubendaParser {
970
  // str_replace - removes double slashes // from url
971
  // preg_replace - removes http or https from url
972
  $haystack = strtok( str_replace( '//', '', preg_replace( "(^https?://)", "", $haystack ) ), '?' );
973
-
974
  if ( fnmatch( $need, $haystack ) !== false )
975
  return $need;
976
  // regular
977
- } else {
978
  if ( strpos( $haystack, $need ) !== false )
979
  return $need;
980
  }
@@ -982,10 +982,10 @@ class iubendaParser {
982
 
983
  return false;
984
  }
985
-
986
  /**
987
  * Custom array merge helper function.
988
- *
989
  * @return array
990
  */
991
  public function array_merge_custom( $builtin, $data ) {
@@ -1005,7 +1005,7 @@ class iubendaParser {
1005
 
1006
  /**
1007
  * Array search helper function.
1008
- *
1009
  * @param type $needle
1010
  * @param type $haystack
1011
  * @return boolean
@@ -1021,4 +1021,4 @@ class iubendaParser {
1021
  return false;
1022
  }
1023
 
1024
- }
1
  <?php
2
  /**
3
  * iubenda.class.php
4
+ *
5
  * @author iubenda s.r.l
6
  * @copyright 2018-2020, iubenda s.r.l
7
  * @license GNU/GPL
8
  * @version 4.1.0
9
  * @deprecated
10
+ *
11
  * This program is free software: you can redistribute it and/or modify
12
  * it under the terms of the GNU General Public License as published by
13
  * the Free Software Foundation, either version 3 of the License, or
35
 
36
  // iframes
37
  public $auto_iframe_tags = array();
38
+
39
  // purposes
40
  public $purposes = array();
41
+
42
  // per-purpose scripts
43
  public $script_tags = array(
44
  // Strictly necessary
71
  'platform.linkedin.com/in.js',
72
  'pinterest.com/js/pinit.js',
73
  'codepen.io',
74
+ 'addthis.com/js/',
75
  'bat.bing.com'
76
  ),
77
  // Analytics
78
  4 => array(
79
  'sharethis.com/button/buttons.js',
 
80
  'scorecardresearch.com/beacon.js',
81
  'neodatagroup.com',
82
  'lp4.io',
104
  'scdn.cxense.com'
105
  )
106
  );
107
+
108
  // per-purpose iframes
109
  public $iframe_tags = array(
110
  // Strictly necessary
156
 
157
  /**
158
  * Construct: the whole HTML output of the page
159
+ *
160
  * @param mixed $content_page
161
  * @param array $args
162
  */
163
  public function __construct( $content_page = '', $args = array() ) {
164
  // valid type?
165
  $this->type = ! empty( $args['type'] ) && in_array( $args['type'], array( 'page', 'faster' ), true ) ? $args['type'] : 'page';
166
+
167
  // amp support>
168
  $this->amp = (bool) ( isset( $args['amp'] ) && $args['amp'] === true );
169
 
190
  $this->auto_script_tags = array_merge( $this->auto_script_tags, $args['scripts'][0] );
191
  unset( $args['scripts'][0] );
192
  }
193
+
194
  $this->script_tags = $this->array_merge_custom( $this->script_tags, $args['scripts'] );
195
  }
196
  }
207
  $this->auto_iframe_tags = array_merge( $this->auto_iframe_tags, $args['iframes'][0] );
208
  unset( $args['iframes'][0] );
209
  }
210
+
211
  $this->iframe_tags = $this->array_merge_custom( $this->iframe_tags, $args['iframes'] );
212
  }
213
  }
221
 
222
  /**
223
  * Static, detect bot & crawler
224
+ *
225
  * @return bool
226
  */
227
  static function bot_detected() {
230
 
231
  /**
232
  * Static, utility function: Return true if the user has already given consent on the page
233
+ *
234
  * @return boolean
235
  */
236
  static function consent_given() {
237
  $consent_given = false;
238
+
239
  foreach ( $_COOKIE as $key => $value ) {
240
  $found = self::strpos_array( $key, array( '_iub_cs-s', '_iub_cs' ) );
241
+
242
  if ( $found !== false ) {
243
  $consent_data = json_decode( stripslashes( $value ), true );
244
+
245
  // read cookie value if given
246
  if ( isset( $consent_data['consent'] ) && $consent_data['consent'] == true )
247
  $consent_given = true;
248
+
249
  // read purposes if given
250
  if ( ! empty( $consent_data['purposes'] ) && is_array( $consent_data['purposes'] ) ) {
251
  // all purposes accepted, consent given
260
 
261
  /**
262
  * Get user accepted purposes.
263
+ *
264
  * @return array
265
  */
266
  static function get_purposes() {
267
  $purposes = array();
268
+
269
  if ( ! empty( $_COOKIE ) ) {
270
  foreach ( $_COOKIE as $key => $value ) {
271
  $found = self::strpos_array( $key, array( '_iub_cs-s', '_iub_cs' ) );
272
+
273
  if ( $found !== false ) {
274
  $consent_data = json_decode( $value, true );
275
+
276
  // read purposes if given
277
+ if ( ! empty( $consent_data['purposes'] ) && is_array( $consent_data['purposes'] ) )
278
  $purposes = $consent_data['purposes'];
279
  }
280
  }
281
  }
282
+
283
  return $purposes;
284
  }
285
+
286
  /**
287
  * Get script tags to be blocked.
288
+ *
289
  * @return array
290
  */
291
  private function get_script_tags() {
292
  $tags = $this->auto_script_tags;
293
+
294
  foreach ( $this->script_tags as $purpose_id => $tags_list ) {
295
  // empty tags list, go to another
296
  if ( empty( $tags_list ) )
297
  continue;
298
+
299
  // purposes available, filter per purpose
300
  if ( ! empty( $this->purposes ) ) {
301
  // don't block scripts unavailable in the user purposes
302
  // if ( array_key_exists( $purpose_id, $this->purposes ) && $this->purposes[$purpose_id] == false ) {
303
+
304
  // block scripts unavailable in the user purposes
305
+ if ( ! isset( $this->purposes[$purpose_id] ) || $this->purposes[$purpose_id] == false ) {
306
  foreach ( $tags_list as $tag ) {
307
  $tags[] = $tag;
308
  }
314
  }
315
  }
316
  }
317
+
318
  return $tags;
319
  }
320
+
321
  /**
322
  * Get iframe tags to be blocked.
323
+ *
324
  * @return array
325
  */
326
  private function get_iframe_tags() {
327
  $tags = $this->auto_iframe_tags;
328
+
329
  foreach ( $this->iframe_tags as $purpose_id => $tags_list ) {
330
  // empty tags list, go to another
331
  if ( empty( $tags_list ) )
332
  continue;
333
+
334
  // purposes available, filter per purpose
335
  if ( ! empty( $this->purposes ) ) {
336
  // don't block iframes unavailable in the user purposes
337
  // if ( array_key_exists( $purpose_id, $this->purposes ) && $this->purposes[$purpose_id] == false ) {
338
+
339
  // block iframes unavailable in the user purposes
340
+ if ( ! isset( $this->purposes[$purpose_id] ) && $this->purposes[$purpose_id] == false ) {
341
  foreach ( $tags_list as $tag ) {
342
  $tags[] = $tag;
343
  }
349
  }
350
  }
351
  }
352
+
353
  return $tags;
354
  }
355
 
356
  /**
357
  * Convert scripts, iframe and other code inside IUBENDAs comment in text/plain to not generate cookies
358
+ *
359
  * @param mixed $content
360
  * @return mixed
361
  */
373
  case 'script':
374
  if ( $args['pattern'] === 'IUB_REGEX_PURPOSE_PATTERN' )
375
  $e->{'data-iub-purposes'} = $args['number'];
376
+
377
  // AMP support
378
  if ( $this->amp )
379
  $e->{'data-block-on-consent'} = '_till_accepted';
387
  case 'iframe':
388
  if ( $args['pattern'] === 'IUB_REGEX_PURPOSE_PATTERN' )
389
  $e->{'data-iub-purposes'} = $args['number'];
390
+
391
  // AMP support
392
  if ( $this->amp )
393
  $e->{'data-block-on-consent'} = '_till_accepted';
412
 
413
  /**
414
  * Skip scripts and iframes inside IUBENDAs comments.
415
+ *
416
  * @param string $content
417
  * @return string
418
  */
445
  }
446
 
447
  /**
448
+ * Parse automatically all the scripts in the page and converts it in text/plain
449
  * if src or the whole output has inside one of the elements in $auto_script_tags array
450
  *
451
  * @return void
455
  case 'page':
456
  // get page contents
457
  $html = str_get_html( $this->content_page, true, true, false );
458
+
459
  if ( is_object( $html ) ) {
460
  // get scripts
461
  $scripts = $html->find( 'script' );
485
 
486
  if ( ! empty( $s->innertext ) ) {
487
  $this->scripts_inline_detected[] = $s->innertext;
488
+
489
  $found = self::strpos_array( $s->innertext, $this->auto_script_tags );
490
 
491
  if ( $found !== false ) {
499
 
500
  if ( $src ) {
501
  $this->scripts_detected[] = $src;
502
+
503
  $found = self::strpos_array( $src, $this->auto_script_tags );
504
 
505
  if ( $found !== false ) {
506
  $class = $s->class;
507
  $s->class = $class . ' ' . $this->iub_class;
508
  $s->type = 'text/plain';
509
+
510
  // add data-iub-purposes attribute
511
  $s->{'data-iub-purposes'} = $this->recursive_array_search( $found, $this->script_tags );
512
+
513
  // AMP support
514
  if ( $this->amp )
515
  $s->{'data-block-on-consent'} = '_till_accepted';
516
+
517
  $this->scripts_converted[] = $src;
518
  }
519
  }
660
  // add inline script as detected
661
  if ( ! empty( $script->nodeValue ) )
662
  $this->scripts_inline_detected[] = $script->nodeValue;
663
+
664
  $found = self::strpos_array( $src, $script_tags );
665
  $found_inline = self::strpos_array( $script->nodeValue, $script_tags );
666
 
667
  if ( $found !== false ) {
668
  $script->setAttribute( 'type', 'text/plain' );
669
  $script->setAttribute( 'class', $script->getAttribute( 'class' ) . ' ' . $class );
670
+
671
  // add data-iub-purposes attribute
672
  $script->setAttribute( 'data-iub-purposes', $this->recursive_array_search( $found, $this->script_tags ) );
673
+
674
  // AMP support
675
  if ( $this->amp )
676
  $script->setAttribute( 'data-block-on-consent', '_till_accepted' );
680
  } elseif ( $found_inline !== false ) {
681
  $script->setAttribute( 'type', 'text/plain' );
682
  $script->setAttribute( 'class', $script->getAttribute( 'class' ) . ' ' . $class_inline );
683
+
684
  // AMP support
685
  if ( $this->amp )
686
  $script->setAttribute( 'data-block-on-consent', '_till_accepted' );
737
 
738
  $src = $i->src;
739
  $this->iframes_detected[] = $src;
740
+
741
  $found = self::strpos_array( $src, $this->auto_iframe_tags );
742
+
743
  if ( $found !== false ) {
744
  $class = $i->class;
745
  $i->suppressedsrc = $src;
746
  $i->src = $this->iub_empty;
747
  $i->class = $class . ' ' . $this->iub_class;
748
+
749
  // add data-iub-purposes attribute
750
  $i->{'data-iub-purposes'} = $this->recursive_array_search( $found, $this->iframe_tags );
751
+
752
  // AMP support
753
  if ( $this->amp )
754
  $i->{'data-block-on-consent'} = '_till_accepted';
755
+
756
  $this->iframes_converted[] = $src;
757
  }
758
  }
803
 
804
  // add iframe as detected
805
  $this->iframes_detected[] = $src;
806
+
807
  $found = self::strpos_array( $src, $iframe_tags );
808
 
809
  if ( $found !== false ) {
810
  $iframe->setAttribute( 'src', $empty );
811
  $iframe->setAttribute( 'suppressedsrc', $src );
812
  $iframe->setAttribute( 'class', $iframe_class . ' ' . $class );
813
+
814
  // per purpose, add data-iub-purposes attribute
815
  $iframe->setAttribute( 'data-iub-purposes', $this->recursive_array_search( $found, $this->iframe_tags ) );
816
+
817
  // AMP support
818
  if ( $this->amp )
819
  $iframe->setAttribute( 'data-block-on-consent', '_till_accepted' );
837
 
838
  /**
839
  * Parse all IUBENDAs comments.
840
+ *
841
  * @return void
842
  */
843
  public function parse_comments() {
919
 
920
  /**
921
  * Return the final page to output
922
+ *
923
  * @return mixed
924
  */
925
  public function get_converted_page() {
928
 
929
  /**
930
  * Print iubenda banner, parameter: the script code of iubenda to print the banner
931
+ *
932
  * @param string $banner
933
  * @return string
934
  */
949
  };
950
  </script>";
951
  }
952
+
953
  /**
954
  * Static, utility function: strpos for array wilth wildcard support
955
+ *
956
  * @param type $haystack
957
  * @param type $needle
958
  * @return boolean
960
  static function strpos_array( $haystack, $needle ) {
961
  if ( empty( $haystack ) || empty( $needle ) )
962
  return false;
963
+
964
  $needle = ! is_array( $needle ) ? array( $needle ) : $needle;
965
 
966
  foreach ( $needle as $need ) {
970
  // str_replace - removes double slashes // from url
971
  // preg_replace - removes http or https from url
972
  $haystack = strtok( str_replace( '//', '', preg_replace( "(^https?://)", "", $haystack ) ), '?' );
973
+
974
  if ( fnmatch( $need, $haystack ) !== false )
975
  return $need;
976
  // regular
977
+ } else {
978
  if ( strpos( $haystack, $need ) !== false )
979
  return $need;
980
  }
982
 
983
  return false;
984
  }
985
+
986
  /**
987
  * Custom array merge helper function.
988
+ *
989
  * @return array
990
  */
991
  public function array_merge_custom( $builtin, $data ) {
1005
 
1006
  /**
1007
  * Array search helper function.
1008
+ *
1009
  * @param type $needle
1010
  * @param type $haystack
1011
  * @return boolean
1021
  return false;
1022
  }
1023
 
1024
+ }
iubenda_cookie_solution.php CHANGED
@@ -1,837 +1,837 @@
1
- <?php
2
- /*
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.3.2
7
- Author: iubenda
8
- Author URI: https://www.iubenda.com
9
- License: MIT License
10
- License URI: http://opensource.org/licenses/MIT
11
- Text Domain: iubenda
12
- Domain Path: /languages
13
-
14
- Cookie and Consent Solution for the GDPR & ePrivacy
15
- Copyright (C) 2018-2020, iubenda s.r.l
16
-
17
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
18
-
19
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
20
-
21
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
- */
23
-
24
- // exit if accessed directly
25
- if ( ! defined( 'ABSPATH' ) )
26
- exit;
27
-
28
- // define contants
29
- define( 'IUB_DEBUG', false );
30
-
31
- /**
32
- * iubenda final class.
33
- *
34
- * @class iubenda
35
- * @version 2.3.2
36
- */
37
- class iubenda {
38
-
39
- private static $instance;
40
- public $options = array();
41
- public $defaults = array(
42
- 'cs' => array(
43
- 'parse' => false, // iubenda_parse
44
- 'skip_parsing' => true, // skip_parsing
45
- 'ctype' => true, // iubenda_ctype
46
- 'parse' => false, // iubenda_parse
47
- 'parser_engine' => 'new', // parser_engine
48
- 'output_feed' => true, // iubenda_output_feed
49
- 'output_post' => true,
50
- 'code_default' => false, // iubenda-code-default,
51
- 'menu_position' => 'topmenu',
52
- 'amp_support' => false,
53
- 'amp_source' => 'local',
54
- 'amp_template_done' => false,
55
- 'amp_template' => '',
56
- 'custom_scripts' => array(),
57
- 'custom_iframes' => array(),
58
- 'deactivation' => false
59
- ),
60
- 'cons' => array(
61
- 'public_api_key' => '',
62
- )
63
- );
64
- public $base_url;
65
- public $version = '2.3.2';
66
- public $activation = array(
67
- 'update_version' => 0,
68
- 'update_notice' => true,
69
- 'update_date' => '',
70
- 'update_delay_date' => 0
71
- );
72
- public $no_html = false;
73
- public $multilang = false;
74
- public $languages = array();
75
- public $lang_default = '';
76
- public $lang_current = '';
77
-
78
- /**
79
- * Disable object clone.
80
- */
81
- private function __clone() {
82
-
83
- }
84
-
85
- /**
86
- * Disable unserializing of the class.
87
- */
88
- private function __wakeup() {
89
-
90
- }
91
-
92
- /**
93
- * Main plugin instance,
94
- * Insures that only one instance of the plugin exists in memory at one time.
95
- *
96
- * @return object
97
- */
98
- public static function instance() {
99
- if ( ! isset( self::$instance ) && ! ( self::$instance instanceof iubenda ) ) {
100
-
101
- self::$instance = new iubenda;
102
- self::$instance->define_constants();
103
-
104
- add_action( 'plugins_loaded', array( self::$instance, 'load_textdomain' ) );
105
- add_action( 'plugins_loaded', array( self::$instance, 'init' ) );
106
-
107
- self::$instance->includes();
108
-
109
- self::$instance->AMP = new iubenda_AMP();
110
- self::$instance->forms = new iubenda_Forms();
111
- self::$instance->settings = new iubenda_Settings();
112
- }
113
-
114
- return self::$instance;
115
- }
116
-
117
- /**
118
- * Class constructor.
119
- */
120
- public function __construct() {
121
- register_activation_hook( __FILE__, array( $this, 'activation' ) );
122
- register_deactivation_hook( __FILE__, array( $this, 'deactivation' ) );
123
-
124
- // settings
125
- $cs_options = (array) get_option( 'iubenda_cookie_law_solution', $this->defaults['cs'] );
126
- $cons_options = (array) get_option( 'iubenda_consent_solution', $this->defaults['cons'] );
127
-
128
- // activate AMP if not available before
129
- if ( function_exists( 'is_amp_endpoint' ) || function_exists( 'ampforwp_is_amp_endpoint' ) ) {
130
- if ( ! isset( $cs_options['amp_support'] ) )
131
- $this->defaults['cs']['amp_support'] = true;
132
- }
133
-
134
- $this->options['cs'] = array_merge( $this->defaults['cs'], $cs_options );
135
- $this->options['cons'] = array_merge( $this->defaults['cons'], $cons_options );
136
-
137
- $this->base_url = esc_url_raw( add_query_arg( 'page', 'iubenda', admin_url( $this->options['cs']['menu_position'] === 'submenu' ? 'options-general.php' : 'admin.php' ) ) );
138
-
139
- // check old custom scripts
140
- if ( ! empty( $this->options['cs']['custom_scripts'] ) && is_array( $this->options['cs']['custom_scripts'] ) && ! is_int( reset( $this->options['cs']['custom_scripts'] ) ) ) {
141
- $data = array();
142
-
143
- foreach ( $this->options['cs']['custom_scripts'] as $script ) {
144
- $data[$script] = 0;
145
- }
146
-
147
- $this->options['cs']['custom_scripts'] = $data;
148
- }
149
-
150
- // check old custom iframes
151
- if ( ! empty( $this->options['cs']['custom_iframes'] ) && is_array( $this->options['cs']['custom_iframes'] ) && ! is_int( reset( $this->options['cs']['custom_iframes'] ) ) ) {
152
- $data = array();
153
-
154
- foreach ( $this->options['cs']['custom_iframes'] as $iframe ) {
155
- $data[$iframe] = 0;
156
- }
157
-
158
- $this->options['cs']['custom_iframes'] = $data;
159
- }
160
-
161
- // actions
162
- add_action( 'after_setup_theme', array( $this, 'register_shortcode' ) );
163
- add_action( 'wp_head', array( $this, 'wp_head_cs' ), 0 );
164
- add_action( 'wp_head', array( $this, 'wp_head_cons' ), 1 );
165
- add_action( 'template_redirect', array( $this, 'output_start' ), 0 );
166
- add_action( 'shutdown', array( $this, 'output_end' ), 100 );
167
- add_action( 'template_redirect', array( $this, 'disable_jetpack_tracking' ) );
168
- add_action( 'admin_init', array( $this, 'maybe_do_upgrade' ) );
169
- add_action( 'upgrader_process_complete', array( $this, 'upgrade' ), 10, 2 );
170
- }
171
-
172
- /**
173
- * Setup plugin constants.
174
- *
175
- * @return void
176
- */
177
- private function define_constants() {
178
- define( 'IUBENDA_PLUGIN_URL', plugins_url( '', __FILE__ ) );
179
- define( 'IUBENDA_PLUGIN_REL_PATH', dirname( plugin_basename( __FILE__ ) ) . '/' );
180
- define( 'IUBENDA_PLUGIN_PATH', plugin_dir_path( __FILE__ ) );
181
- }
182
-
183
- /**
184
- * Include required files.
185
- *
186
- * @return void
187
- */
188
- private function includes() {
189
- include_once( IUBENDA_PLUGIN_PATH . 'includes/settings.php' );
190
- include_once( IUBENDA_PLUGIN_PATH . 'includes/forms.php' );
191
- include_once( IUBENDA_PLUGIN_PATH . 'includes/amp.php' );
192
- }
193
-
194
- /**
195
- * Initialize plugin.
196
- *
197
- * @return void
198
- */
199
- public function init() {
200
- // check if WPML or Polylang is active
201
- include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
202
-
203
- // Polylang support
204
- if ( ( is_plugin_active( 'polylang/polylang.php' ) || is_plugin_active( 'polylang-pro/polylang.php' ) ) && function_exists( 'PLL' ) ) {
205
- $this->multilang = true;
206
-
207
- // get registered languages
208
- $registered_languages = PLL()->model->get_languages_list();
209
-
210
- if ( ! empty( $registered_languages ) ) {
211
- foreach ( $registered_languages as $language )
212
- $this->languages[$language->slug] = $language->name;
213
- }
214
-
215
- // get default language
216
- $this->lang_default = pll_default_language();
217
- // get current language
218
- $this->lang_current = pll_current_language();
219
-
220
- // WPML support
221
- } elseif ( is_plugin_active( 'sitepress-multilingual-cms/sitepress.php' ) && class_exists( 'SitePress' ) ) {
222
- $this->multilang = true;
223
-
224
- global $sitepress;
225
-
226
- // get registered languages
227
- $registered_languages = icl_get_languages();
228
-
229
- if ( ! empty( $registered_languages ) ) {
230
- foreach ( $registered_languages as $language )
231
- $this->languages[$language['code']] = $language['display_name'];
232
- }
233
-
234
- // get default language
235
- $this->lang_default = $sitepress->get_default_language();
236
- // get current language
237
- $this->lang_current = $sitepress->get_current_language();
238
- }
239
-
240
- // load iubenda parser
241
- include_once( dirname( __FILE__ ) . '/iubenda-cookie-class/iubenda.class.php' );
242
- }
243
-
244
- /**
245
- * Plugin activation.
246
- *
247
- * @return void
248
- */
249
- public function activation() {
250
- set_transient( 'iub_activation_completed', 1, 3600 );
251
-
252
- add_option( 'iubenda_cookie_law_solution', $this->options['cs'], '', 'no' );
253
- add_option( 'iubenda_cookie_law_solution', $this->options['cons'], '', 'no' );
254
- add_option( 'iubenda_cookie_law_version', $this->version, '', 'no' );
255
- add_option( 'iubenda_activation_data', $this->activation, '', 'no' );
256
- }
257
-
258
- /**
259
- * Plugin deactivation.
260
- *
261
- * @return void
262
- */
263
- public function deactivation() {
264
- // remove options from database?
265
- if ( $this->options['cs']['deactivation'] ) {
266
- delete_option( 'iubenda_cookie_law_solution' );
267
- delete_option( 'iubenda_consent_solution' );
268
- delete_option( 'iubenda_cookie_law_version' );
269
- delete_option( 'iubenda_activation_data' );
270
- }
271
- }
272
-
273
- /**
274
- * Plugin upgrae.
275
- *
276
- * @return void
277
- */
278
- public function upgrade( $upgrader_object, $options ) {
279
- // the path to our plugin's main file
280
- $our_plugin = plugin_basename( __FILE__ );
281
-
282
- // if an update has taken place and the updated type is plugins and the plugins element exists
283
- if ( $options['action'] == 'update' && $options['type'] == 'plugin' && isset( $options['plugins'] ) ) {
284
- // iterate through the plugins being updated and check if ours is there
285
- foreach ( $options['plugins'] as $plugin ) {
286
- if ( $plugin == $our_plugin ) {
287
- // set a transient to record that our plugin has just been updated
288
- set_transient( 'iub_upgrade_completed', 1, 3600 );
289
- }
290
- }
291
- }
292
- }
293
-
294
- /**
295
- * Load textdomain.
296
- *
297
- * @return void
298
- */
299
- public function load_textdomain() {
300
- load_plugin_textdomain( 'iubenda', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
301
- }
302
-
303
- /**
304
- * Register shortcode function.
305
- *
306
- * @return void
307
- */
308
- public function register_shortcode() {
309
- add_shortcode( 'iub-cookie-policy', array( $this, 'block_shortcode' ) );
310
- add_shortcode( 'iub-cookie-block', array( $this, 'block_shortcode' ) );
311
- add_shortcode( 'iub-cookie-skip', array( $this, 'skip_shortcode' ) );
312
- }
313
-
314
- /**
315
- * Handle block shortcode function.
316
- *
317
- * @param array $atts
318
- * @param mixed $content
319
- * @return mixed
320
- */
321
- public function block_shortcode( $atts, $content = '' ) {
322
- return '<!--IUB-COOKIE-BLOCK-START-->' . do_shortcode( $content ) . '<!--IUB-COOKIE-BLOCK-END-->';
323
- }
324
-
325
- /**
326
- * Handle skip shortcode function.
327
- *
328
- * @param array $atts
329
- * @param mixed $content
330
- * @return mixed
331
- */
332
- public function skip_shortcode( $atts, $content = '' ) {
333
- return '<!--IUB-COOKIE-BLOCK-SKIP-START-->' . do_shortcode( $content ) . '<!--IUB-COOKIE-BLOCK-SKIP-END-->';
334
- }
335
-
336
- /**
337
- * Add wp_head cookie soution content.
338
- *
339
- * @return mixed
340
- */
341
- public function wp_head_cs() {
342
-
343
- // check content type
344
- if ( (bool) $this->options['cs']['ctype'] == true ) {
345
- $iub_headers = headers_list();
346
- $destroy = true;
347
-
348
- foreach ( $iub_headers as $header ) {
349
- if ( strpos( $header, "Content-Type: text/html" ) !== false || strpos( $header, "Content-type: text/html" ) !== false ) {
350
- $destroy = false;
351
- break;
352
- }
353
- }
354
-
355
- if ( $destroy )
356
- $this->no_html = true;
357
- }
358
-
359
- // is post or not html content type?
360
- if ( ( $_POST && $this->options['cs']['output_post'] ) || $this->no_html )
361
- return;
362
-
363
- // initial head output
364
- $iubenda_code = '';
365
-
366
- if ( $this->multilang === true && defined( 'ICL_LANGUAGE_CODE' ) && isset( $this->options['cs']['code_' . ICL_LANGUAGE_CODE] ) ) {
367
- $iubenda_code .= $this->options['cs']['code_' . ICL_LANGUAGE_CODE];
368
-
369
- // no code for current language, use default
370
- if ( ! $iubenda_code )
371
- $iubenda_code .= $this->options['cs']['code_default'];
372
- } else
373
- $iubenda_code .= $this->options['cs']['code_default'];
374
-
375
- $iubenda_code = $this->parse_code( $iubenda_code, true );
376
-
377
- if ( $iubenda_code !== '' ) {
378
- $iubenda_code .= "\n
379
- <script>
380
- var iCallback = function() {};
381
- var _iub = _iub || {};
382
-
383
- if ( typeof _iub.csConfiguration != 'undefined' ) {
384
- if ( 'callback' in _iub.csConfiguration ) {
385
- if ( 'onConsentGiven' in _iub.csConfiguration.callback )
386
- iCallback = _iub.csConfiguration.callback.onConsentGiven;
387
-
388
- _iub.csConfiguration.callback.onConsentGiven = function() {
389
- iCallback();
390
-
391
- /* separator */
392
- jQuery('noscript._no_script_iub').each(function (a, b) { var el = jQuery(b); el.after(el.html()); });
393
- }
394
- }
395
- }
396
- </script>";
397
-
398
- echo '<!--IUB-COOKIE-SKIP-START-->' . $iubenda_code . '<!--IUB-COOKIE-SKIP-END-->';
399
- }
400
- }
401
-
402
- /**
403
- * Add wp_head consent solution content.
404
- *
405
- * @return mixed
406
- */
407
- public function wp_head_cons() {
408
- if ( ! empty( $this->options['cons']['public_api_key'] ) ) {
409
-
410
- $parameters = apply_filters( 'iubenda_cons_init_parameters', array(
411
- 'log_level' => 'error',
412
- 'logger' => 'console',
413
- 'send_from_local' => true
414
- ) );
415
-
416
- echo '<!-- Library initialization -->
417
- <script type="text/javascript">
418
- var _iub = _iub || { };
419
-
420
- _iub.cons_instructions = _iub.cons_instructions || [ ];
421
- _iub.cons_instructions.push(
422
- [ "init", {
423
- api_key: "' . $this->options['cons']['public_api_key'] . '",
424
- log_level: "' . $parameters['log_level'] . '",
425
- logger: "' . ( ! empty( $parameters['logger'] ) && in_array( $parameters['logger'], array( 'console', 'none' ) ) ? $parameters['logger'] : 'console' ) . '",
426
- sendFromLocalStorageAtLoad: ' . ( (bool) ( $parameters['send_from_local'] ) ? 'true' : 'false' ) . '
427
- }, function ( ) {
428
- // console.log( "init callBack" );
429
- }
430
- ]
431
- );
432
- </script>
433
- <script type="text/javascript" src="//cdn.iubenda.com/cons/iubenda_cons.js" async></script>';
434
- }
435
- }
436
-
437
- /**
438
- * Initialize html output.
439
- *
440
- * @return void
441
- */
442
- public function output_start() {
443
- if ( ! is_admin() )
444
- ob_start( array( $this, 'output_callback' ) );
445
- }
446
-
447
- /**
448
- * Finish html output.
449
- *
450
- * @return void
451
- */
452
- public function output_end() {
453
- if ( ! is_admin() && ob_get_level() )
454
- ob_end_flush();
455
- }
456
-
457
- /**
458
- * Handle final html output.
459
- *
460
- * @param mixed $output
461
- * @return mixed
462
- */
463
- public function output_callback( $output ) {
464
- // check whether to run parser or not
465
- // bail on ajax, xmlrpc or iub_no_parse request
466
- if (
467
- ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST ) || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) || isset( $_SERVER["HTTP_X_REQUESTED_WITH"] ) || isset( $_GET['iub_no_parse'] )
468
- )
469
- return $output;
470
-
471
- // bail on admin side
472
- if ( is_admin() )
473
- return $output;
474
-
475
- // bail on rss feed
476
- if ( is_feed() && $this->options['cs']['output_feed'] )
477
- return $output;
478
-
479
- if ( strpos( $output, "<html" ) === false )
480
- return $output;
481
- elseif ( strpos( $output, "<html" ) > 200 )
482
- return $output;
483
-
484
- // bail if skripts blocking disabled
485
- if ( ! $this->options['cs']['parse'] )
486
- return $output;
487
-
488
- // bail if consent given and skip parsing enabled
489
- if ( iubendaParser::consent_given() && $this->options['cs']['skip_parsing'] )
490
- return $output;
491
-
492
- // bail on POST request
493
- if ( $_POST && $this->options['cs']['output_post'] )
494
- return $output;
495
-
496
- // bail if bot detectd, no html in output or it's a post request
497
- if ( iubendaParser::bot_detected() || $this->no_html )
498
- return $output;
499
-
500
- // google recaptcha v3 compatibility
501
- if ( class_exists( 'WPCF7' ) && (int) WPCF7::get_option( 'iqfix_recaptcha' ) === 0 && ! iubendaParser::consent_given() )
502
- $this->options['cs']['custom_scripts']['grecaptcha'] = 2;
503
-
504
- // Jetpack compatibility
505
- if ( class_exists( 'Jetpack' ) )
506
- $this->options['cs']['custom_scripts']['stats.wp.com'] = 5;
507
-
508
- $startime = microtime( true );
509
- $output = apply_filters( 'iubenda_initial_output', $output );
510
-
511
- // prepare scripts and iframes
512
- $scripts = $this->prepare_custom_data( $this->options['cs']['custom_scripts'] );
513
- $iframes = $this->prepare_custom_data( $this->options['cs']['custom_iframes'] );
514
-
515
- // experimental class
516
- if ( $this->options['cs']['parser_engine'] == 'new' ) {
517
- $iubenda = new iubendaParser( mb_convert_encoding( $output, 'HTML-ENTITIES', 'UTF-8' ), array(
518
- 'type' => 'faster',
519
- 'amp' => $this->options['cs']['amp_support'],
520
- 'scripts' => $scripts,
521
- 'iframes' => $iframes
522
- ) );
523
-
524
- // render output
525
- $output = $iubenda->parse();
526
-
527
- // append signature
528
- $output .= '<!-- Parsed with iubenda experimental class in ' . round( microtime( true ) - $startime, 4 ) . ' sec. -->';
529
- // default class
530
- } else {
531
- $iubenda = new iubendaParser( $output, array(
532
- 'type' => 'page',
533
- 'amp' => $this->options['cs']['amp_support'],
534
- 'scripts' => $scripts,
535
- 'iframes' => $iframes
536
- ) );
537
-
538
- // render output
539
- $output = $iubenda->parse();
540
-
541
- // append signature
542
- $output .= '<!-- Parsed with iubenda default class in ' . round( microtime( true ) - $startime, 4 ) . ' sec. -->';
543
- }
544
-
545
- return apply_filters( 'iubenda_final_output', $output );
546
- }
547
-
548
- /**
549
- * Prepare scripts/iframes.
550
- *
551
- * @param array $data
552
- * @return array
553
- */
554
- public function prepare_custom_data( $data ) {
555
- $newdata = array();
556
-
557
- foreach ( $data as $script => $type ) {
558
- if ( ! array_key_exists( $type, $newdata ) )
559
- $newdata[$type] = array();
560
-
561
- $newdata[$type][] = $script;
562
- }
563
-
564
- return $newdata;
565
- }
566
-
567
- /**
568
- * Parse iubenda code.
569
- *
570
- * @param string $source
571
- * @param bool $display
572
- * @return string
573
- */
574
- public function parse_code( $source, $display = false ) {
575
- // return $source;
576
- $source = trim( $source );
577
-
578
- preg_match_all( '/(\"(?:html|content)\"(?:\s+)?\:(?:\s+)?)\"((?:.*?)(?:[^\\\\]))\"/s', $source, $matches );
579
-
580
- // found subgroup?
581
- if ( ! empty( $matches[1] ) && ! empty( $matches[2] ) ) {
582
- foreach ( $matches[2] as $no => $match ) {
583
- $source = str_replace( $matches[0][$no], $matches[1][$no] . '[[IUBENDA_TAG_START]]' . $match . '[[IUBENDA_TAG_END]]', $source );
584
- }
585
-
586
- // kses it
587
- $source = wp_kses( $source, $this->get_allowed_html() );
588
-
589
- preg_match_all( '/\[\[IUBENDA_TAG_START\]\](.*?)\[\[IUBENDA_TAG_END\]\]/s', $source, $matches_tags );
590
-
591
- if ( ! empty( $matches_tags[1] ) ) {
592
- foreach ( $matches_tags[1] as $no => $match ) {
593
- $source = str_replace( $matches_tags[0][$no], '"' . ( $display ? str_replace( '</', '<\/', $matches[2][$no] ) : $matches[2][$no] ) . '"', $source );
594
- }
595
- }
596
- }
597
-
598
- return $source;
599
- }
600
-
601
- /**
602
- * Disable Jetpack tracking on AMO cached pages.
603
- *
604
- * @return void
605
- */
606
- public function disable_jetpack_tracking() {
607
- // bail no Jetpack active
608
- if ( ! class_exists( 'Jetpack' ) )
609
- return;
610
-
611
- // disable if it's not AMP cached request
612
- if ( ! class_exists( 'Jetpack_AMP_Support' ) || ! Jetpack_AMP_Support::is_amp_request() )
613
- return;
614
-
615
- // if ( is_feed() || is_robots() || is_trackback() || is_preview() || jetpack_is_dnt_enabled() )
616
- // bail if skripts blocking disabled
617
- if ( ! $this->options['cs']['parse'] )
618
- return;
619
-
620
- // bail if consent given and skip parsing enabled
621
- if ( iubendaParser::consent_given() && $this->options['cs']['skip_parsing'] )
622
- return;
623
-
624
- remove_action( 'wp_head', 'stats_add_shutdown_action' );
625
- remove_action( 'wp_footer', 'stats_footer', 101 );
626
- }
627
-
628
- /**
629
- * Perform actions on plugin installation/upgrade.
630
- *
631
- * @return void
632
- */
633
- public function maybe_do_upgrade() {
634
- if ( ! current_user_can( 'install_plugins' ) )
635
- return;
636
-
637
- // bail if no activation or upgrade transient is set
638
- if ( ! get_transient( 'iub_upgrade_completed' ) && ! get_transient( 'iub_activation_completed' ) )
639
- return;
640
-
641
- // delete the activation transient
642
- delete_transient( 'iub_activation_completed' );
643
- // delete the upgrade transient
644
- delete_transient( 'iub_upgrade_completed' );
645
-
646
- // bail if activating from network, or bulk, or within an iFrame
647
- if ( is_network_admin() || isset( $_GET['activate-multi'] ) || defined( 'IFRAME_REQUEST' ) )
648
- return;
649
-
650
- // generate AMP template file if AMP plugins available
651
- if ( function_exists( 'is_amp_endpoint' ) || function_exists( 'ampforwp_is_amp_endpoint' ) ) {
652
- iubenda()->AMP->generate_amp_template();
653
- }
654
- }
655
-
656
- /**
657
- * Get configuration data parsed from iubenda code
658
- *
659
- * @param type $iubenda_code
660
- * @param type $args
661
- * @return type
662
- */
663
- public function parse_configuration( $code, $args = array() ) {
664
- $configuration = array();
665
- $defaults = array(
666
- 'mode' => 'basic',
667
- 'parse' => false
668
- );
669
-
670
- // parse incoming $args into an array and merge it with $defaults
671
- $args = wp_parse_args( $args, $defaults );
672
-
673
- if ( empty( $code ) )
674
- return $configuration;
675
-
676
- // parse code if needed
677
- $parsed_code = $args['parse'] === true ? $this->parse_code( $code, true ) : $code;
678
-
679
- // get script
680
- $parsed_script = '';
681
-
682
- preg_match_all( '/src\=(?:[\"|\'])(.*?)(?:[\"|\'])/', $parsed_code, $matches );
683
-
684
- // find the iubenda script url
685
- if ( ! empty( $matches[1] ) ) {
686
- foreach ( $matches[1] as $found_script ) {
687
- if ( wp_http_validate_url( $found_script ) && strpos( $found_script, 'iubenda_cs.js' ) ) {
688
- $parsed_script = $found_script;
689
- continue;
690
- }
691
- }
692
- }
693
-
694
- // strip tags
695
- $parsed_code = wp_kses( $parsed_code, array() );
696
-
697
- // get configuration
698
- preg_match( '/_iub.csConfiguration *= *{(.*?)\};/', $parsed_code, $matches );
699
-
700
- if ( ! empty( $matches[1] ) )
701
- $parsed_code = '{' . $matches[1] . '}';
702
-
703
- // decode
704
- $decoded = json_decode( $parsed_code, true );
705
-
706
- if ( ! empty( $decoded ) && is_array( $decoded ) ) {
707
-
708
- $decoded['script'] = $parsed_script;
709
-
710
- // basic mode
711
- if ( $args['mode'] === 'basic' ) {
712
- if ( isset( $decoded['banner'] ) )
713
- unset( $decoded['banner'] );
714
- if ( isset( $decoded['callback'] ) )
715
- unset( $decoded['callback'] );
716
- if ( isset( $decoded['perPurposeConsent'] ) )
717
- unset( $decoded['perPurposeConsent'] );
718
- }
719
-
720
- $configuration = $decoded;
721
- }
722
-
723
- return $configuration;
724
- }
725
-
726
- /**
727
- * Domain info helper function.
728
- *
729
- * @param type $domainb
730
- * @return type
731
- */
732
- public function domain( $domainb ) {
733
- $bits = explode( '/', $domainb );
734
- if ( $bits[0] == 'http:' || $bits[0] == 'https:' ) {
735
- $domainb = $bits[2];
736
- } else {
737
- $domainb = $bits[0];
738
- }
739
- unset( $bits );
740
- $bits = explode( '.', $domainb );
741
- $idz = 0;
742
- while ( isset( $bits[$idz] ) ) {
743
- $idz += 1;
744
- }
745
- $idz -= 3;
746
- $idy = 0;
747
- while ( $idy < $idz ) {
748
- unset( $bits[$idy] );
749
- $idy += 1;
750
- }
751
- $part = array();
752
- foreach ( $bits AS $bit ) {
753
- $part[] = $bit;
754
- }
755
- unset( $bit );
756
- unset( $bits );
757
- unset( $domainb );
758
- $domainb = '';
759
-
760
- if ( strlen( $part[1] ) > 3 ) {
761
- unset( $part[0] );
762
- }
763
- foreach ( $part AS $bit ) {
764
- $domainb .= $bit . '.';
765
- }
766
- unset( $bit );
767
-
768
- return preg_replace( '/(.*)\./', '$1', $domainb );
769
- }
770
-
771
- /**
772
- * Check if file exists helper function.
773
- *
774
- * @param type $file
775
- */
776
- public function file_exists( $file ) {
777
- $file_headers = @get_headers( $file );
778
-
779
- if ( ! $file_headers || $file_headers[0] == 'HTTP/1.1 404 Not Found' ) {
780
- $exists = false;
781
- } else {
782
- $exists = true;
783
- }
784
- }
785
-
786
- /**
787
- * Get allowed iubenda script HTML.
788
- *
789
- * @return array
790
- */
791
- public function get_allowed_html() {
792
- // Jetpack fix
793
- remove_filter( 'pre_kses', array( 'Filter_Embedded_HTML_Objects', 'filter' ), 11 );
794
-
795
- $html = array_merge(
796
- wp_kses_allowed_html( 'post' ), array(
797
- 'script' => array(
798
- 'type' => array(),
799
- 'src' => array(),
800
- 'charset' => array(),
801
- 'async' => array()
802
- ),
803
- 'noscript' => array(),
804
- 'style' => array(
805
- 'type' => array()
806
- ),
807
- 'iframe' => array(
808
- 'src' => array(),
809
- 'height' => array(),
810
- 'width' => array(),
811
- 'frameborder' => array(),
812
- 'allowfullscreen' => array()
813
- )
814
- )
815
- );
816
-
817
- return apply_filters( 'iub_code_allowed_html', $html );
818
- }
819
-
820
- }
821
-
822
- /**
823
- * Initialise iubenda Cookie Solution
824
- *
825
- * @return object
826
- */
827
- function iubenda() {
828
- static $instance;
829
-
830
- // first call to instance() initializes the plugin
831
- if ( $instance === null || ! ( $instance instanceof iubenda ) )
832
- $instance = iubenda::instance();
833
-
834
- return $instance;
835
- }
836
-
837
- $iubenda = iubenda();
1
+ <?php
2
+ /*
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.3.3
7
+ Author: iubenda
8
+ Author URI: https://www.iubenda.com
9
+ License: MIT License
10
+ License URI: http://opensource.org/licenses/MIT
11
+ Text Domain: iubenda
12
+ Domain Path: /languages
13
+
14
+ Cookie and Consent Solution for the GDPR & ePrivacy
15
+ Copyright (C) 2018-2020, iubenda s.r.l
16
+
17
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
18
+
19
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
20
+
21
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ */
23
+
24
+ // exit if accessed directly
25
+ if ( ! defined( 'ABSPATH' ) )
26
+ exit;
27
+
28
+ // define contants
29
+ define( 'IUB_DEBUG', false );
30
+
31
+ /**
32
+ * iubenda final class.
33
+ *
34
+ * @class iubenda
35
+ * @version 2.3.3
36
+ */
37
+ class iubenda {
38
+
39
+ private static $instance;
40
+ public $options = array();
41
+ public $defaults = array(
42
+ 'cs' => array(
43
+ 'parse' => false, // iubenda_parse
44
+ 'skip_parsing' => true, // skip_parsing
45
+ 'ctype' => true, // iubenda_ctype
46
+ 'parse' => false, // iubenda_parse
47
+ 'parser_engine' => 'new', // parser_engine
48
+ 'output_feed' => true, // iubenda_output_feed
49
+ 'output_post' => true,
50
+ 'code_default' => false, // iubenda-code-default,
51
+ 'menu_position' => 'topmenu',
52
+ 'amp_support' => false,
53
+ 'amp_source' => 'local',
54
+ 'amp_template_done' => false,
55
+ 'amp_template' => '',
56
+ 'custom_scripts' => array(),
57
+ 'custom_iframes' => array(),
58
+ 'deactivation' => false
59
+ ),
60
+ 'cons' => array(
61
+ 'public_api_key' => '',
62
+ )
63
+ );
64
+ public $base_url;
65
+ public $version = '2.3.3';
66
+ public $activation = array(
67
+ 'update_version' => 0,
68
+ 'update_notice' => true,
69
+ 'update_date' => '',
70
+ 'update_delay_date' => 0
71
+ );
72
+ public $no_html = false;
73
+ public $multilang = false;
74
+ public $languages = array();
75
+ public $lang_default = '';
76
+ public $lang_current = '';
77
+
78
+ /**
79
+ * Disable object clone.
80
+ */
81
+ private function __clone() {
82
+
83
+ }
84
+
85
+ /**
86
+ * Disable unserializing of the class.
87
+ */
88
+ private function __wakeup() {
89
+
90
+ }
91
+
92
+ /**
93
+ * Main plugin instance,
94
+ * Insures that only one instance of the plugin exists in memory at one time.
95
+ *
96
+ * @return object
97
+ */
98
+ public static function instance() {
99
+ if ( ! isset( self::$instance ) && ! ( self::$instance instanceof iubenda ) ) {
100
+
101
+ self::$instance = new iubenda;
102
+ self::$instance->define_constants();
103
+
104
+ add_action( 'plugins_loaded', array( self::$instance, 'load_textdomain' ) );
105
+ add_action( 'plugins_loaded', array( self::$instance, 'init' ) );
106
+
107
+ self::$instance->includes();
108
+
109
+ self::$instance->AMP = new iubenda_AMP();
110
+ self::$instance->forms = new iubenda_Forms();
111
+ self::$instance->settings = new iubenda_Settings();
112
+ }
113
+
114
+ return self::$instance;
115
+ }
116
+
117
+ /**
118
+ * Class constructor.
119
+ */
120
+ public function __construct() {
121
+ register_activation_hook( __FILE__, array( $this, 'activation' ) );
122
+ register_deactivation_hook( __FILE__, array( $this, 'deactivation' ) );
123
+
124
+ // settings
125
+ $cs_options = (array) get_option( 'iubenda_cookie_law_solution', $this->defaults['cs'] );
126
+ $cons_options = (array) get_option( 'iubenda_consent_solution', $this->defaults['cons'] );
127
+
128
+ // activate AMP if not available before
129
+ if ( function_exists( 'is_amp_endpoint' ) || function_exists( 'ampforwp_is_amp_endpoint' ) ) {
130
+ if ( ! isset( $cs_options['amp_support'] ) )
131
+ $this->defaults['cs']['amp_support'] = true;
132
+ }
133
+
134
+ $this->options['cs'] = array_merge( $this->defaults['cs'], $cs_options );
135
+ $this->options['cons'] = array_merge( $this->defaults['cons'], $cons_options );
136
+
137
+ $this->base_url = esc_url_raw( add_query_arg( 'page', 'iubenda', admin_url( $this->options['cs']['menu_position'] === 'submenu' ? 'options-general.php' : 'admin.php' ) ) );
138
+
139
+ // check old custom scripts
140
+ if ( ! empty( $this->options['cs']['custom_scripts'] ) && is_array( $this->options['cs']['custom_scripts'] ) && ! is_int( reset( $this->options['cs']['custom_scripts'] ) ) ) {
141
+ $data = array();
142
+
143
+ foreach ( $this->options['cs']['custom_scripts'] as $script ) {
144
+ $data[$script] = 0;
145
+ }
146
+
147
+ $this->options['cs']['custom_scripts'] = $data;
148
+ }
149
+
150
+ // check old custom iframes
151
+ if ( ! empty( $this->options['cs']['custom_iframes'] ) && is_array( $this->options['cs']['custom_iframes'] ) && ! is_int( reset( $this->options['cs']['custom_iframes'] ) ) ) {
152
+ $data = array();
153
+
154
+ foreach ( $this->options['cs']['custom_iframes'] as $iframe ) {
155
+ $data[$iframe] = 0;
156
+ }
157
+
158
+ $this->options['cs']['custom_iframes'] = $data;
159
+ }
160
+
161
+ // actions
162
+ add_action( 'after_setup_theme', array( $this, 'register_shortcode' ) );
163
+ add_action( 'wp_head', array( $this, 'wp_head_cs' ), 0 );
164
+ add_action( 'wp_head', array( $this, 'wp_head_cons' ), 1 );
165
+ add_action( 'template_redirect', array( $this, 'output_start' ), 0 );
166
+ add_action( 'shutdown', array( $this, 'output_end' ), 100 );
167
+ add_action( 'template_redirect', array( $this, 'disable_jetpack_tracking' ) );
168
+ add_action( 'admin_init', array( $this, 'maybe_do_upgrade' ) );
169
+ add_action( 'upgrader_process_complete', array( $this, 'upgrade' ), 10, 2 );
170
+ }
171
+
172
+ /**
173
+ * Setup plugin constants.
174
+ *
175
+ * @return void
176
+ */
177
+ private function define_constants() {
178
+ define( 'IUBENDA_PLUGIN_URL', plugins_url( '', __FILE__ ) );
179
+ define( 'IUBENDA_PLUGIN_REL_PATH', dirname( plugin_basename( __FILE__ ) ) . '/' );
180
+ define( 'IUBENDA_PLUGIN_PATH', plugin_dir_path( __FILE__ ) );
181
+ }
182
+
183
+ /**
184
+ * Include required files.
185
+ *
186
+ * @return void
187
+ */
188
+ private function includes() {
189
+ include_once( IUBENDA_PLUGIN_PATH . 'includes/settings.php' );
190
+ include_once( IUBENDA_PLUGIN_PATH . 'includes/forms.php' );
191
+ include_once( IUBENDA_PLUGIN_PATH . 'includes/amp.php' );
192
+ }
193
+
194
+ /**
195
+ * Initialize plugin.
196
+ *
197
+ * @return void
198
+ */
199
+ public function init() {
200
+ // check if WPML or Polylang is active
201
+ include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
202
+
203
+ // Polylang support
204
+ if ( ( is_plugin_active( 'polylang/polylang.php' ) || is_plugin_active( 'polylang-pro/polylang.php' ) ) && function_exists( 'PLL' ) ) {
205
+ $this->multilang = true;
206
+
207
+ // get registered languages
208
+ $registered_languages = PLL()->model->get_languages_list();
209
+
210
+ if ( ! empty( $registered_languages ) ) {
211
+ foreach ( $registered_languages as $language )
212
+ $this->languages[$language->slug] = $language->name;
213
+ }
214
+
215
+ // get default language
216
+ $this->lang_default = pll_default_language();
217
+ // get current language
218
+ $this->lang_current = pll_current_language();
219
+
220
+ // WPML support
221
+ } elseif ( is_plugin_active( 'sitepress-multilingual-cms/sitepress.php' ) && class_exists( 'SitePress' ) ) {
222
+ $this->multilang = true;
223
+
224
+ global $sitepress;
225
+
226
+ // get registered languages
227
+ $registered_languages = icl_get_languages();
228
+
229
+ if ( ! empty( $registered_languages ) ) {
230
+ foreach ( $registered_languages as $language )
231
+ $this->languages[$language['code']] = $language['display_name'];
232
+ }
233
+
234
+ // get default language
235
+ $this->lang_default = $sitepress->get_default_language();
236
+ // get current language
237
+ $this->lang_current = $sitepress->get_current_language();
238
+ }
239
+
240
+ // load iubenda parser
241
+ include_once( dirname( __FILE__ ) . '/iubenda-cookie-class/iubenda.class.php' );
242
+ }
243
+
244
+ /**
245
+ * Plugin activation.
246
+ *
247
+ * @return void
248
+ */
249
+ public function activation() {
250
+ set_transient( 'iub_activation_completed', 1, 3600 );
251
+
252
+ add_option( 'iubenda_cookie_law_solution', $this->options['cs'], '', 'no' );
253
+ add_option( 'iubenda_cookie_law_solution', $this->options['cons'], '', 'no' );
254
+ add_option( 'iubenda_cookie_law_version', $this->version, '', 'no' );
255
+ add_option( 'iubenda_activation_data', $this->activation, '', 'no' );
256
+ }
257
+
258
+ /**
259
+ * Plugin deactivation.
260
+ *
261
+ * @return void
262
+ */
263
+ public function deactivation() {
264
+ // remove options from database?
265
+ if ( $this->options['cs']['deactivation'] ) {
266
+ delete_option( 'iubenda_cookie_law_solution' );
267
+ delete_option( 'iubenda_consent_solution' );
268
+ delete_option( 'iubenda_cookie_law_version' );
269
+ delete_option( 'iubenda_activation_data' );
270
+ }
271
+ }
272
+
273
+ /**
274
+ * Plugin upgrae.
275
+ *
276
+ * @return void
277
+ */
278
+ public function upgrade( $upgrader_object, $options ) {
279
+ // the path to our plugin's main file
280
+ $our_plugin = plugin_basename( __FILE__ );
281
+
282
+ // if an update has taken place and the updated type is plugins and the plugins element exists
283
+ if ( $options['action'] == 'update' && $options['type'] == 'plugin' && isset( $options['plugins'] ) ) {
284
+ // iterate through the plugins being updated and check if ours is there
285
+ foreach ( $options['plugins'] as $plugin ) {
286
+ if ( $plugin == $our_plugin ) {
287
+ // set a transient to record that our plugin has just been updated
288
+ set_transient( 'iub_upgrade_completed', 1, 3600 );
289
+ }
290
+ }
291
+ }
292
+ }
293
+
294
+ /**
295
+ * Load textdomain.
296
+ *
297
+ * @return void
298
+ */
299
+ public function load_textdomain() {
300
+ load_plugin_textdomain( 'iubenda', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
301
+ }
302
+
303
+ /**
304
+ * Register shortcode function.
305
+ *
306
+ * @return void
307
+ */
308
+ public function register_shortcode() {
309
+ add_shortcode( 'iub-cookie-policy', array( $this, 'block_shortcode' ) );
310
+ add_shortcode( 'iub-cookie-block', array( $this, 'block_shortcode' ) );
311
+ add_shortcode( 'iub-cookie-skip', array( $this, 'skip_shortcode' ) );
312
+ }
313
+
314
+ /**
315
+ * Handle block shortcode function.
316
+ *
317
+ * @param array $atts
318
+ * @param mixed $content
319
+ * @return mixed
320
+ */
321
+ public function block_shortcode( $atts, $content = '' ) {
322
+ return '<!--IUB-COOKIE-BLOCK-START-->' . do_shortcode( $content ) . '<!--IUB-COOKIE-BLOCK-END-->';
323
+ }
324
+
325
+ /**
326
+ * Handle skip shortcode function.
327
+ *
328
+ * @param array $atts
329
+ * @param mixed $content
330
+ * @return mixed
331
+ */
332
+ public function skip_shortcode( $atts, $content = '' ) {
333
+ return '<!--IUB-COOKIE-BLOCK-SKIP-START-->' . do_shortcode( $content ) . '<!--IUB-COOKIE-BLOCK-SKIP-END-->';
334
+ }
335
+
336
+ /**
337
+ * Add wp_head cookie soution content.
338
+ *
339
+ * @return mixed
340
+ */
341
+ public function wp_head_cs() {
342
+
343
+ // check content type
344
+ if ( (bool) $this->options['cs']['ctype'] == true ) {
345
+ $iub_headers = headers_list();
346
+ $destroy = true;
347
+
348
+ foreach ( $iub_headers as $header ) {
349
+ if ( strpos( $header, "Content-Type: text/html" ) !== false || strpos( $header, "Content-type: text/html" ) !== false ) {
350
+ $destroy = false;
351
+ break;
352
+ }
353
+ }
354
+
355
+ if ( $destroy )
356
+ $this->no_html = true;
357
+ }
358
+
359
+ // is post or not html content type?
360
+ if ( ( $_POST && $this->options['cs']['output_post'] ) || $this->no_html )
361
+ return;
362
+
363
+ // initial head output
364
+ $iubenda_code = '';
365
+
366
+ if ( $this->multilang === true && defined( 'ICL_LANGUAGE_CODE' ) && isset( $this->options['cs']['code_' . ICL_LANGUAGE_CODE] ) ) {
367
+ $iubenda_code .= $this->options['cs']['code_' . ICL_LANGUAGE_CODE];
368
+
369
+ // no code for current language, use default
370
+ if ( ! $iubenda_code )
371
+ $iubenda_code .= $this->options['cs']['code_default'];
372
+ } else
373
+ $iubenda_code .= $this->options['cs']['code_default'];
374
+
375
+ $iubenda_code = $this->parse_code( $iubenda_code, true );
376
+
377
+ if ( $iubenda_code !== '' ) {
378
+ $iubenda_code .= "\n
379
+ <script>
380
+ var iCallback = function() {};
381
+ var _iub = _iub || {};
382
+
383
+ if ( typeof _iub.csConfiguration != 'undefined' ) {
384
+ if ( 'callback' in _iub.csConfiguration ) {
385
+ if ( 'onConsentGiven' in _iub.csConfiguration.callback )
386
+ iCallback = _iub.csConfiguration.callback.onConsentGiven;
387
+
388
+ _iub.csConfiguration.callback.onConsentGiven = function() {
389
+ iCallback();
390
+
391
+ /* separator */
392
+ jQuery('noscript._no_script_iub').each(function (a, b) { var el = jQuery(b); el.after(el.html()); });
393
+ }
394
+ }
395
+ }
396
+ </script>";
397
+
398
+ echo '<!--IUB-COOKIE-SKIP-START-->' . $iubenda_code . '<!--IUB-COOKIE-SKIP-END-->';
399
+ }
400
+ }
401
+
402
+ /**
403
+ * Add wp_head consent solution content.
404
+ *
405
+ * @return mixed
406
+ */
407
+ public function wp_head_cons() {
408
+ if ( ! empty( $this->options['cons']['public_api_key'] ) ) {
409
+
410
+ $parameters = apply_filters( 'iubenda_cons_init_parameters', array(
411
+ 'log_level' => 'error',
412
+ 'logger' => 'console',
413
+ 'send_from_local' => true
414
+ ) );
415
+
416
+ echo '<!-- Library initialization -->
417
+ <script type="text/javascript">
418
+ var _iub = _iub || { };
419
+
420
+ _iub.cons_instructions = _iub.cons_instructions || [ ];
421
+ _iub.cons_instructions.push(
422
+ [ "init", {
423
+ api_key: "' . $this->options['cons']['public_api_key'] . '",
424
+ log_level: "' . $parameters['log_level'] . '",
425
+ logger: "' . ( ! empty( $parameters['logger'] ) && in_array( $parameters['logger'], array( 'console', 'none' ) ) ? $parameters['logger'] : 'console' ) . '",
426
+ sendFromLocalStorageAtLoad: ' . ( (bool) ( $parameters['send_from_local'] ) ? 'true' : 'false' ) . '
427
+ }, function ( ) {
428
+ // console.log( "init callBack" );
429
+ }
430
+ ]
431
+ );
432
+ </script>
433
+ <script type="text/javascript" src="//cdn.iubenda.com/cons/iubenda_cons.js" async></script>';
434
+ }
435
+ }
436
+
437
+ /**
438
+ * Initialize html output.
439
+ *
440
+ * @return void
441
+ */
442
+ public function output_start() {
443
+ if ( ! is_admin() )
444
+ ob_start( array( $this, 'output_callback' ) );
445
+ }
446
+
447
+ /**
448
+ * Finish html output.
449
+ *
450
+ * @return void
451
+ */
452
+ public function output_end() {
453
+ if ( ! is_admin() && ob_get_level() )
454
+ ob_end_flush();
455
+ }
456
+
457
+ /**
458
+ * Handle final html output.
459
+ *
460
+ * @param mixed $output
461
+ * @return mixed
462
+ */
463
+ public function output_callback( $output ) {
464
+ // check whether to run parser or not
465
+ // bail on ajax, xmlrpc or iub_no_parse request
466
+ if (
467
+ ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST ) || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) || isset( $_SERVER["HTTP_X_REQUESTED_WITH"] ) || isset( $_GET['iub_no_parse'] )
468
+ )
469
+ return $output;
470
+
471
+ // bail on admin side
472
+ if ( is_admin() )
473
+ return $output;
474
+
475
+ // bail on rss feed
476
+ if ( is_feed() && $this->options['cs']['output_feed'] )
477
+ return $output;
478
+
479
+ if ( strpos( $output, "<html" ) === false )
480
+ return $output;
481
+ elseif ( strpos( $output, "<html" ) > 200 )
482
+ return $output;
483
+
484
+ // bail if skripts blocking disabled
485
+ if ( ! $this->options['cs']['parse'] )
486
+ return $output;
487
+
488
+ // bail if consent given and skip parsing enabled
489
+ if ( iubendaParser::consent_given() && $this->options['cs']['skip_parsing'] )
490
+ return $output;
491
+
492
+ // bail on POST request
493
+ if ( $_POST && $this->options['cs']['output_post'] )
494
+ return $output;
495
+
496
+ // bail if bot detectd, no html in output or it's a post request
497
+ if ( iubendaParser::bot_detected() || $this->no_html )
498
+ return $output;
499
+
500
+ // google recaptcha v3 compatibility
501
+ if ( class_exists( 'WPCF7' ) && (int) WPCF7::get_option( 'iqfix_recaptcha' ) === 0 && ! iubendaParser::consent_given() )
502
+ $this->options['cs']['custom_scripts']['grecaptcha'] = 2;
503
+
504
+ // Jetpack compatibility
505
+ if ( class_exists( 'Jetpack' ) )
506
+ $this->options['cs']['custom_scripts']['stats.wp.com'] = 5;
507
+
508
+ $startime = microtime( true );
509
+ $output = apply_filters( 'iubenda_initial_output', $output );
510
+
511
+ // prepare scripts and iframes
512
+ $scripts = $this->prepare_custom_data( $this->options['cs']['custom_scripts'] );
513
+ $iframes = $this->prepare_custom_data( $this->options['cs']['custom_iframes'] );
514
+
515
+ // experimental class
516
+ if ( $this->options['cs']['parser_engine'] == 'new' ) {
517
+ $iubenda = new iubendaParser( mb_convert_encoding( $output, 'HTML-ENTITIES', 'UTF-8' ), array(
518
+ 'type' => 'faster',
519
+ 'amp' => $this->options['cs']['amp_support'],
520
+ 'scripts' => $scripts,
521
+ 'iframes' => $iframes
522
+ ) );
523
+
524
+ // render output
525
+ $output = $iubenda->parse();
526
+
527
+ // append signature
528
+ $output .= '<!-- Parsed with iubenda experimental class in ' . round( microtime( true ) - $startime, 4 ) . ' sec. -->';
529
+ // default class
530
+ } else {
531
+ $iubenda = new iubendaParser( $output, array(
532
+ 'type' => 'page',
533
+ 'amp' => $this->options['cs']['amp_support'],
534
+ 'scripts' => $scripts,
535
+ 'iframes' => $iframes
536
+ ) );
537
+
538
+ // render output
539
+ $output = $iubenda->parse();
540
+
541
+ // append signature
542
+ $output .= '<!-- Parsed with iubenda default class in ' . round( microtime( true ) - $startime, 4 ) . ' sec. -->';
543
+ }
544
+
545
+ return apply_filters( 'iubenda_final_output', $output );
546
+ }
547
+
548
+ /**
549
+ * Prepare scripts/iframes.
550
+ *
551
+ * @param array $data
552
+ * @return array
553
+ */
554
+ public function prepare_custom_data( $data ) {
555
+ $newdata = array();
556
+
557
+ foreach ( $data as $script => $type ) {
558
+ if ( ! array_key_exists( $type, $newdata ) )
559
+ $newdata[$type] = array();
560
+
561
+ $newdata[$type][] = $script;
562
+ }
563
+
564
+ return $newdata;
565
+ }
566
+
567
+ /**
568
+ * Parse iubenda code.
569
+ *
570
+ * @param string $source
571
+ * @param bool $display
572
+ * @return string
573
+ */
574
+ public function parse_code( $source, $display = false ) {
575
+ // return $source;
576
+ $source = trim( $source );
577
+
578
+ preg_match_all( '/(\"(?:html|content)\"(?:\s+)?\:(?:\s+)?)\"((?:.*?)(?:[^\\\\]))\"/s', $source, $matches );
579
+
580
+ // found subgroup?
581
+ if ( ! empty( $matches[1] ) && ! empty( $matches[2] ) ) {
582
+ foreach ( $matches[2] as $no => $match ) {
583
+ $source = str_replace( $matches[0][$no], $matches[1][$no] . '[[IUBENDA_TAG_START]]' . $match . '[[IUBENDA_TAG_END]]', $source );
584
+ }
585
+
586
+ // kses it
587
+ $source = wp_kses( $source, $this->get_allowed_html() );
588
+
589
+ preg_match_all( '/\[\[IUBENDA_TAG_START\]\](.*?)\[\[IUBENDA_TAG_END\]\]/s', $source, $matches_tags );
590
+
591
+ if ( ! empty( $matches_tags[1] ) ) {
592
+ foreach ( $matches_tags[1] as $no => $match ) {
593
+ $source = str_replace( $matches_tags[0][$no], '"' . ( $display ? str_replace( '</', '<\/', $matches[2][$no] ) : $matches[2][$no] ) . '"', $source );
594
+ }
595
+ }
596
+ }
597
+
598
+ return $source;
599
+ }
600
+
601
+ /**
602
+ * Disable Jetpack tracking on AMO cached pages.
603
+ *
604
+ * @return void
605
+ */
606
+ public function disable_jetpack_tracking() {
607
+ // bail no Jetpack active
608
+ if ( ! class_exists( 'Jetpack' ) )
609
+ return;
610
+
611
+ // disable if it's not AMP cached request
612
+ if ( ! class_exists( 'Jetpack_AMP_Support' ) || ! Jetpack_AMP_Support::is_amp_request() )
613
+ return;
614
+
615
+ // if ( is_feed() || is_robots() || is_trackback() || is_preview() || jetpack_is_dnt_enabled() )
616
+ // bail if skripts blocking disabled
617
+ if ( ! $this->options['cs']['parse'] )
618
+ return;
619
+
620
+ // bail if consent given and skip parsing enabled
621
+ if ( iubendaParser::consent_given() && $this->options['cs']['skip_parsing'] )
622
+ return;
623
+
624
+ remove_action( 'wp_head', 'stats_add_shutdown_action' );
625
+ remove_action( 'wp_footer', 'stats_footer', 101 );
626
+ }
627
+
628
+ /**
629
+ * Perform actions on plugin installation/upgrade.
630
+ *
631
+ * @return void
632
+ */
633
+ public function maybe_do_upgrade() {
634
+ if ( ! current_user_can( 'install_plugins' ) )
635
+ return;
636
+
637
+ // bail if no activation or upgrade transient is set
638
+ if ( ! get_transient( 'iub_upgrade_completed' ) && ! get_transient( 'iub_activation_completed' ) )
639
+ return;
640
+
641
+ // delete the activation transient
642
+ delete_transient( 'iub_activation_completed' );
643
+ // delete the upgrade transient
644
+ delete_transient( 'iub_upgrade_completed' );
645
+
646
+ // bail if activating from network, or bulk, or within an iFrame
647
+ if ( is_network_admin() || isset( $_GET['activate-multi'] ) || defined( 'IFRAME_REQUEST' ) )
648
+ return;
649
+
650
+ // generate AMP template file if AMP plugins available
651
+ if ( function_exists( 'is_amp_endpoint' ) || function_exists( 'ampforwp_is_amp_endpoint' ) ) {
652
+ iubenda()->AMP->generate_amp_template();
653
+ }
654
+ }
655
+
656
+ /**
657
+ * Get configuration data parsed from iubenda code
658
+ *
659
+ * @param type $iubenda_code
660
+ * @param type $args
661
+ * @return type
662
+ */
663
+ public function parse_configuration( $code, $args = array() ) {
664
+ $configuration = array();
665
+ $defaults = array(
666
+ 'mode' => 'basic',
667
+ 'parse' => false
668
+ );
669
+
670
+ // parse incoming $args into an array and merge it with $defaults
671
+ $args = wp_parse_args( $args, $defaults );
672
+
673
+ if ( empty( $code ) )
674
+ return $configuration;
675
+
676
+ // parse code if needed
677
+ $parsed_code = $args['parse'] === true ? $this->parse_code( $code, true ) : $code;
678
+
679
+ // get script
680
+ $parsed_script = '';
681
+
682
+ preg_match_all( '/src\=(?:[\"|\'])(.*?)(?:[\"|\'])/', $parsed_code, $matches );
683
+
684
+ // find the iubenda script url
685
+ if ( ! empty( $matches[1] ) ) {
686
+ foreach ( $matches[1] as $found_script ) {
687
+ if ( wp_http_validate_url( $found_script ) && strpos( $found_script, 'iubenda_cs.js' ) ) {
688
+ $parsed_script = $found_script;
689
+ continue;
690
+ }
691
+ }
692
+ }
693
+
694
+ // strip tags
695
+ $parsed_code = wp_kses( $parsed_code, array() );
696
+
697
+ // get configuration
698
+ preg_match( '/_iub.csConfiguration *= *{(.*?)\};/', $parsed_code, $matches );
699
+
700
+ if ( ! empty( $matches[1] ) )
701
+ $parsed_code = '{' . $matches[1] . '}';
702
+
703
+ // decode
704
+ $decoded = json_decode( $parsed_code, true );
705
+
706
+ if ( ! empty( $decoded ) && is_array( $decoded ) ) {
707
+
708
+ $decoded['script'] = $parsed_script;
709
+
710
+ // basic mode
711
+ if ( $args['mode'] === 'basic' ) {
712
+ if ( isset( $decoded['banner'] ) )
713
+ unset( $decoded['banner'] );
714
+ if ( isset( $decoded['callback'] ) )
715
+ unset( $decoded['callback'] );
716
+ if ( isset( $decoded['perPurposeConsent'] ) )
717
+ unset( $decoded['perPurposeConsent'] );
718
+ }
719
+
720
+ $configuration = $decoded;
721
+ }
722
+
723
+ return $configuration;
724
+ }
725
+
726
+ /**
727
+ * Domain info helper function.
728
+ *
729
+ * @param type $domainb
730
+ * @return type
731
+ */
732
+ public function domain( $domainb ) {
733
+ $bits = explode( '/', $domainb );
734
+ if ( $bits[0] == 'http:' || $bits[0] == 'https:' ) {
735
+ $domainb = $bits[2];
736
+ } else {
737
+ $domainb = $bits[0];
738
+ }
739
+ unset( $bits );
740
+ $bits = explode( '.', $domainb );
741
+ $idz = 0;
742
+ while ( isset( $bits[$idz] ) ) {
743
+ $idz += 1;
744
+ }
745
+ $idz -= 3;
746
+ $idy = 0;
747
+ while ( $idy < $idz ) {
748
+ unset( $bits[$idy] );
749
+ $idy += 1;
750
+ }
751
+ $part = array();
752
+ foreach ( $bits AS $bit ) {
753
+ $part[] = $bit;
754
+ }
755
+ unset( $bit );
756
+ unset( $bits );
757
+ unset( $domainb );
758
+ $domainb = '';
759
+
760
+ if ( strlen( $part[1] ) > 3 ) {
761
+ unset( $part[0] );
762
+ }
763
+ foreach ( $part AS $bit ) {
764
+ $domainb .= $bit . '.';
765
+ }
766
+ unset( $bit );
767
+
768
+ return preg_replace( '/(.*)\./', '$1', $domainb );
769
+ }
770
+
771
+ /**
772
+ * Check if file exists helper function.
773
+ *
774
+ * @param type $file
775
+ */
776
+ public function file_exists( $file ) {
777
+ $file_headers = @get_headers( $file );
778
+
779
+ if ( ! $file_headers || $file_headers[0] == 'HTTP/1.1 404 Not Found' ) {
780
+ $exists = false;
781
+ } else {
782
+ $exists = true;
783
+ }
784
+ }
785
+
786
+ /**
787
+ * Get allowed iubenda script HTML.
788
+ *
789
+ * @return array
790
+ */
791
+ public function get_allowed_html() {
792
+ // Jetpack fix
793
+ remove_filter( 'pre_kses', array( 'Filter_Embedded_HTML_Objects', 'filter' ), 11 );
794
+
795
+ $html = array_merge(
796
+ wp_kses_allowed_html( 'post' ), array(
797
+ 'script' => array(
798
+ 'type' => array(),
799
+ 'src' => array(),
800
+ 'charset' => array(),
801
+ 'async' => array()
802
+ ),
803
+ 'noscript' => array(),
804
+ 'style' => array(
805
+ 'type' => array()
806
+ ),
807
+ 'iframe' => array(
808
+ 'src' => array(),
809
+ 'height' => array(),
810
+ 'width' => array(),
811
+ 'frameborder' => array(),
812
+ 'allowfullscreen' => array()
813
+ )
814
+ )
815
+ );
816
+
817
+ return apply_filters( 'iub_code_allowed_html', $html );
818
+ }
819
+
820
+ }
821
+
822
+ /**
823
+ * Initialise iubenda Cookie Solution
824
+ *
825
+ * @return object
826
+ */
827
+ function iubenda() {
828
+ static $instance;
829
+
830
+ // first call to instance() initializes the plugin
831
+ if ( $instance === null || ! ( $instance instanceof iubenda ) )
832
+ $instance = iubenda::instance();
833
+
834
+ return $instance;
835
+ }
836
+
837
+ $iubenda = iubenda();
js/frontend.js CHANGED
@@ -1,188 +1,188 @@
1
- ( function ( $ ) {
2
-
3
- $( document ).ready( function () {
4
-
5
- var iubendaConsentSolution = new function () {
6
- var _this = this;
7
-
8
- // parse args
9
- var args = $.parseJSON( iubForms );
10
-
11
- // console.log( args );
12
-
13
- // get forms
14
- this.init = function () {
15
- // loop though plugins
16
- if ( $( args ).length > 0 ) {
17
- $.each( args, function( source, forms ) {
18
- // loop through forms
19
- if ( $( forms ).length > 0 ) {
20
- $.each( forms, function( id, form ) {
21
- // console.log( form );
22
-
23
- // get corresponding html form id
24
- switch ( source ) {
25
-
26
- // WooCommerce Checkout Form
27
- case 'woocommerce' :
28
- var htmlFormContainer = $( '.woocommerce-checkout' );
29
-
30
- // form exists, let's use it
31
- if ( htmlFormContainer.length > 0 ) {
32
- // setup vars
33
- formArgs = {
34
- submitElement: null,
35
- form: {
36
- selector: document.querySelectorAll( 'form.woocommerce-checkout' )[0],
37
- map: form.form.map
38
- }
39
- };
40
-
41
- // handle ajax submit
42
- $( htmlFormContainer ).on( 'checkout_place_order', function( e ) {
43
- _this.submitForm( form, formArgs );
44
-
45
- _iub.cons.sendData();
46
- // don't send before page refresh
47
- // on succcessfull submit it will be sent automatically
48
- // _iub.cons.sendFromLocalStorage();
49
- } );
50
- }
51
-
52
- break;
53
-
54
- // WordPress Comment Form
55
- case 'wp_comment_form' :
56
- var htmlFormContainer = $( '#commentform' );
57
-
58
- // form exists, let's use it
59
- if ( htmlFormContainer.length > 0 ) {
60
- // adjust submit element id
61
- var submitElement = document.getElementById( htmlFormContainer.attr( 'id' ) ).querySelectorAll( 'input[type=submit]' )[0];
62
-
63
- /* id="submit" override
64
- if ( typeof submitElement !== 'undefined' && submitElement.name == 'submit' ) {
65
- submitElement.id = 'wp-comment-submit';
66
- submitElement.name = 'wp-comment-submit';
67
- }
68
- */
69
-
70
- // setup vars
71
- formArgs = {
72
- // submitElement: submitElement,
73
- submitElement: null,
74
- form: {
75
- selector: document.getElementById( htmlFormContainer.attr( 'id' ) ),
76
- map: form.form.map
77
- }
78
- };
79
-
80
- $( submitElement ).on( 'click touchstart', function( e ) {
81
- _this.submitForm( form, formArgs );
82
-
83
- _iub.cons.sendData();
84
- // don't send before page refresh
85
- // on succcessfull submit it will be sent automatically
86
- // _iub.cons.sendFromLocalStorage();
87
- } );
88
- }
89
-
90
- break;
91
-
92
- // Contact Form 7
93
- case 'wpcf7' :
94
- // var regex = new RegExp( '^wpcf7-f([0-9]*)-' );
95
- var htmlFormContainer = $( 'div[id^="wpcf7-f' + id + '-"]' );
96
-
97
- // form exists, let's use it
98
- if ( htmlFormContainer.length > 0 ) {
99
- var selector = document.getElementById( htmlFormContainer.attr( 'id' ) ).getElementsByClassName( 'wpcf7-form' )[0];
100
-
101
- // handle ajax submit
102
- $( document ).on( 'wpcf7mailsent', selector, function( e ) {
103
- // setup vars
104
- formArgs = {
105
- // submitElement: document.getElementById( htmlFormContainer.attr( 'id' ) ).getElementsByClassName( 'wpcf7-submit' )[0],
106
- submitElement: null,
107
- form: {
108
- selector: selector,
109
- map: form.form.map
110
- }
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();
118
- _iub.cons.sendFromLocalStorage();
119
- }
120
- } );
121
-
122
- };
123
-
124
- break;
125
-
126
- // WP Forms
127
- case 'wpforms' :
128
- var htmlFormContainer = $( 'div[id^="wpforms-' + id + '"]' );
129
-
130
- // form exists, let's use it
131
- if ( htmlFormContainer.length > 0 ) {
132
- var selector = document.getElementById( 'wpforms-form-' + id );
133
- var isAjax = $( '#wpforms-form-' + id ).hasClass( 'wpforms-ajax-form' );
134
-
135
- // handle ajax submit
136
- $( document ).on( 'wpformsAjaxSubmitSuccess', selector, function( e ) {
137
- // setup vars
138
- formArgs = {
139
- submitElement: ( isAjax ? null : document.getElementById( 'wpforms-submit-' + id ) ),
140
- form: {
141
- selector: selector,
142
- map: form.form.map
143
- }
144
- };
145
-
146
- // send only if specific form has been submitted
147
- if ( selector.id == e.target.id ) {
148
- _this.submitForm( form, formArgs );
149
-
150
- _iub.cons.sendData();
151
- _iub.cons.sendFromLocalStorage();
152
- }
153
- } );
154
- };
155
-
156
- break;
157
- }
158
-
159
- // console.log( source );
160
-
161
- } );
162
- }
163
- } );
164
- }
165
- };
166
-
167
- // submit form
168
- this.submitForm = function ( form, formArgs ) {
169
- // push consent vars
170
- if ( typeof form.consent !== 'undefined' && form.consent.legal_notices.length > 0 ) {
171
- formArgs.consent = {};
172
- formArgs.consent.legal_notices = form.consent.legal_notices;
173
- }
174
-
175
- console.log( formArgs );
176
-
177
- // build form consent data
178
- _iub.cons_instructions.push( [ 'load', formArgs ] );
179
- };
180
-
181
- };
182
-
183
- // initialize
184
- iubendaConsentSolution.init();
185
-
186
- } );
187
-
188
  } )( jQuery );
1
+ ( function ( $ ) {
2
+
3
+ $( document ).ready( function () {
4
+
5
+ var iubendaConsentSolution = new function () {
6
+ var _this = this;
7
+
8
+ // parse args
9
+ var args = $.parseJSON( iubForms );
10
+
11
+ // console.log( args );
12
+
13
+ // get forms
14
+ this.init = function () {
15
+ // loop though plugins
16
+ if ( $( args ).length > 0 ) {
17
+ $.each( args, function( source, forms ) {
18
+ // loop through forms
19
+ if ( $( forms ).length > 0 ) {
20
+ $.each( forms, function( id, form ) {
21
+ // console.log( form );
22
+
23
+ // get corresponding html form id
24
+ switch ( source ) {
25
+
26
+ // WooCommerce Checkout Form
27
+ case 'woocommerce' :
28
+ var htmlFormContainer = $( '.woocommerce-checkout' );
29
+
30
+ // form exists, let's use it
31
+ if ( htmlFormContainer.length > 0 ) {
32
+ // setup vars
33
+ formArgs = {
34
+ submitElement: null,
35
+ form: {
36
+ selector: document.querySelectorAll( 'form.woocommerce-checkout' )[0],
37
+ map: form.form.map
38
+ }
39
+ };
40
+
41
+ // handle ajax submit
42
+ $( htmlFormContainer ).on( 'checkout_place_order', function( e ) {
43
+ _this.submitForm( form, formArgs );
44
+
45
+ _iub.cons.sendData();
46
+ // don't send before page refresh
47
+ // on succcessfull submit it will be sent automatically
48
+ // _iub.cons.sendFromLocalStorage();
49
+ } );
50
+ }
51
+
52
+ break;
53
+
54
+ // WordPress Comment Form
55
+ case 'wp_comment_form' :
56
+ var htmlFormContainer = $( '#commentform' );
57
+
58
+ // form exists, let's use it
59
+ if ( htmlFormContainer.length > 0 ) {
60
+ // adjust submit element id
61
+ var submitElement = document.getElementById( htmlFormContainer.attr( 'id' ) ).querySelectorAll( 'input[type=submit]' )[0];
62
+
63
+ /* id="submit" override
64
+ if ( typeof submitElement !== 'undefined' && submitElement.name == 'submit' ) {
65
+ submitElement.id = 'wp-comment-submit';
66
+ submitElement.name = 'wp-comment-submit';
67
+ }
68
+ */
69
+
70
+ // setup vars
71
+ formArgs = {
72
+ // submitElement: submitElement,
73
+ submitElement: null,
74
+ form: {
75
+ selector: document.getElementById( htmlFormContainer.attr( 'id' ) ),
76
+ map: form.form.map
77
+ }
78
+ };
79
+
80
+ $( submitElement ).on( 'click touchstart', function( e ) {
81
+ _this.submitForm( form, formArgs );
82
+
83
+ _iub.cons.sendData();
84
+ // don't send before page refresh
85
+ // on succcessfull submit it will be sent automatically
86
+ // _iub.cons.sendFromLocalStorage();
87
+ } );
88
+ }
89
+
90
+ break;
91
+
92
+ // Contact Form 7
93
+ case 'wpcf7' :
94
+ // var regex = new RegExp( '^wpcf7-f([0-9]*)-' );
95
+ var htmlFormContainer = $( 'div[id^="wpcf7-f' + id + '-"]' );
96
+
97
+ // form exists, let's use it
98
+ if ( htmlFormContainer.length > 0 ) {
99
+ var selector = document.getElementById( htmlFormContainer.attr( 'id' ) ).getElementsByClassName( 'wpcf7-form' )[0];
100
+
101
+ // handle ajax submit
102
+ $( document ).on( 'wpcf7mailsent', selector, function( e ) {
103
+ // setup vars
104
+ formArgs = {
105
+ // submitElement: document.getElementById( htmlFormContainer.attr( 'id' ) ).getElementsByClassName( 'wpcf7-submit' )[0],
106
+ submitElement: null,
107
+ form: {
108
+ selector: selector,
109
+ map: form.form.map
110
+ }
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();
118
+ _iub.cons.sendFromLocalStorage();
119
+ }
120
+ } );
121
+
122
+ };
123
+
124
+ break;
125
+
126
+ // WP Forms
127
+ case 'wpforms' :
128
+ var htmlFormContainer = $( 'div[id^="wpforms-' + id + '"]' );
129
+
130
+ // form exists, let's use it
131
+ if ( htmlFormContainer.length > 0 ) {
132
+ var selector = document.getElementById( 'wpforms-form-' + id );
133
+ var isAjax = $( '#wpforms-form-' + id ).hasClass( 'wpforms-ajax-form' );
134
+
135
+ // handle ajax submit
136
+ $( document ).on( 'wpformsAjaxSubmitSuccess', selector, function( e ) {
137
+ // setup vars
138
+ formArgs = {
139
+ submitElement: ( isAjax ? null : document.getElementById( 'wpforms-submit-' + id ) ),
140
+ form: {
141
+ selector: selector,
142
+ map: form.form.map
143
+ }
144
+ };
145
+
146
+ // send only if specific form has been submitted
147
+ if ( selector.id == e.target.id ) {
148
+ _this.submitForm( form, formArgs );
149
+
150
+ _iub.cons.sendData();
151
+ _iub.cons.sendFromLocalStorage();
152
+ }
153
+ } );
154
+ };
155
+
156
+ break;
157
+ }
158
+
159
+ // console.log( source );
160
+
161
+ } );
162
+ }
163
+ } );
164
+ }
165
+ };
166
+
167
+ // submit form
168
+ this.submitForm = function ( form, formArgs ) {
169
+ // push consent vars
170
+ if ( typeof form.consent !== 'undefined' && form.consent.legal_notices.length > 0 ) {
171
+ formArgs.consent = {};
172
+ formArgs.consent.legal_notices = form.consent.legal_notices;
173
+ }
174
+
175
+ console.log( formArgs );
176
+
177
+ // build form consent data
178
+ _iub.cons_instructions.push( [ 'load', formArgs ] );
179
+ };
180
+
181
+ };
182
+
183
+ // initialize
184
+ iubendaConsentSolution.init();
185
+
186
+ } );
187
+
188
  } )( jQuery );
readme.txt CHANGED
@@ -1,438 +1,441 @@
1
- === iubenda - Cookie and Consent Solution for the GDPR & ePrivacy ===
2
- Contributors: iubenda
3
- Donate link:
4
- Tags: cookies, cookie law, cookie policy, cookie banner, privacy policy, cookie consent, privacy, gdpr, eprivacy
5
- Requires at least: 4.0
6
- Requires PHP: 5.2.4
7
- Tested up to: 5.3.2
8
- Stable tag: 2.3.2
9
- License: MIT License
10
- License URI: http://opensource.org/licenses/MIT
11
-
12
- 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.
13
-
14
- == Description ==
15
-
16
- This plugin is an All-in-One approach developed by iubenda, which includes functionalities of two powerful solutions (see below) that help to make your website GDPR and ePrivacy compliant. The plugin lets you automate the implementation of ePrivacy (Cookie Law) and GDPR requirements by providing a fully customizable cookie banner, blocking scripts, and by managing all aspects of cookie consent. It also allows you to record, review, and maintain comprehensive GDPR records of consent for your web-forms.
17
-
18
- == Cookie Solution ==
19
-
20
- This plugin drastically reduces the need for direct interventions in the code of the site by integrating with iubenda’s Cookie Solution. It provides a fully customizable cookie banner, dynamically generates a cookie policy to [match the services in use on your site](https://www.iubenda.com/en/help/19004-how-to-use-the-site-scanner-from-within-the-generator), and, fully manages cookie-related consent – including the blocking of the most common widgets and third-party cookies before consent is received – in order to comply with the GDPR and ePrivacy.
21
-
22
- **Key features:**
23
-
24
- * The plugin automatically inserts the iubenda code in the head of every page of the site
25
- * Allows you to automatically or manually block scripts that can install cookies prior to consent, without the need of direct intervention on the code
26
- * Allows you to autodetect and limit prior-blocking and cookie consent requests only to users from the EU – where this is a legal requirement – while running cookies scripts normally in regions where you are still legally allowed to do so.
27
- * Asynchronously re-activates cookie scripts once consent is collected.
28
- * Handles the display of the cookie banner and cookie policy, allowing you to fully customize the banner to match the look and colors of your site if needed
29
- * California Consumer Privacy Act [(CCPA) Support](https://www.iubenda.com/en/help/21165-ccpa-how-to-add-a-notice-of-collection-and-a-do-not-sell-link)
30
- * Saves user preferences about the use of cookies and displays a clean page (without banner) to users who have already provided their consent
31
- * Integrates with IAB’s [Transparency and Consent Framework](https://www.iubenda.com/en/help/7440-enable-preference-management-iab-framework#revenue) (TCF)
32
- * Allows you to provide you users with granular, per-category preference control (e.g. basic functionalities, experience enhancement, targeting & advertising)
33
- * Compatible with Google's Accelerated Mobile Pages (AMP)
34
- * Features an easy-to-use interface for entering custom scripts and iframes
35
- * Detects bots/spiders and serves them a clean page so that your SEO efforts are never compromised
36
-
37
- **The plugin is currently capable of automatically detecting and blocking the following scripts:**
38
-
39
- * Google Analytics
40
- * Google Maps
41
- * Google AdSense
42
- * Google ReCaptcha
43
- * Google Site Search
44
- * Google Tag Manager
45
- * Google oAuth
46
- * Google+ widgets
47
- * Twitter widgets
48
- * Facebook widgets
49
- * Facebook Comments
50
- * YouTube
51
- * Vimeo
52
- * Linkedin widgets
53
- * ShareThis widgets
54
- * Instagram widgets
55
- * AddThis widgets
56
- * Pinterest widgets
57
- * PayPal widgets
58
- * Disqus
59
- * Optimizely
60
- * Neodata
61
- * Criteo
62
- * Outbrain
63
- * Headway
64
- * Codepen
65
- * Freshchat
66
- * Uservoice
67
- * AdRoll
68
- * Olark
69
- * Segment
70
- * Kissmetrics
71
- * Mixpanel
72
- * Pingdom
73
- * Bing
74
- * Elevio
75
-
76
- == Consent Solution ==
77
-
78
- Maintaining valid records of consent is a vital part of privacy compliance in general, and it is specifically required under the GDPR. These records should include a userid, timestamp, consent proof, record of the consenting action, and the legal documents available to the user at the time of consent, among other things. This plugin **is THE most complete solution for recording, sorting and maintaining GDPR records of consent**. The plugin also boasts built-in compatibility with WordPress comment form, Contact Form 7 and WP Forms plugins for your convenience, but can be manually integrated with any type of web-form and can even store consent proofs for consents collected offline (e.g in-store sign-ups) via WP media upload.
79
-
80
- **Key features:**
81
-
82
- * The plugin detects and identifies all supported forms that are embedded in the website
83
- * It’s auto-compatible with and allows super easy mapping of Contact Form 7, WP Forms, WordPress comment and WooCommerce checkout forms
84
- * It allows manual integration with any type of web-form
85
- * For each consent, track the form/wording the user was prompted with
86
- * Flexibly upload any form of proof of consent or legal notice, including a PDF if consent was collected offline
87
- * It provides a high granularity: map individual form fields, exclude fields (like password inputs), add legal notices available at the time of consent collection, indicate double opt-in, set preferences and more
88
- * REST HTTP API and JS SDK, to give you total control and how and when consent is stored
89
- * Store multiple preferences for each user (e.g. if you have multiple newsletters or opt-ins)
90
- * Features an easy-to-use interface for entering custom scripts and iframes
91
- * It provides API input field for quick and easy activation
92
-
93
- **Some background information**
94
-
95
- If you potentially have any European users, you must comply with laws like the [GDPR](https://www.iubenda.com/en/help/5428-gdpr-guide#consent) and [ePrivacy](https://www.iubenda.com/en/help/6293-cookie-consent-management-faq). These laws are precise in their requirements and technical implementation can be pretty complicated. We've tried to make this process as painless as possible for website and app owners with our suite of compliance software solutions.
96
- Our Cookie and Consent Solution plugin for WordPress simplifies and manages these compliance requirements within a few clicks. This extension works with the iubenda [Cookie Solution](https://www.iubenda.com/en/cookie-solution) and [Consent Solution](https://www.iubenda.com/en/consent-solution).
97
-
98
- **Which languages does iubenda work in currently?**
99
-
100
- * English
101
- * Italian
102
- * French
103
- * Spanish
104
- * Portuguese (Brazilian)
105
- * German
106
- * Dutch
107
- * Russian
108
-
109
- == Installation ==
110
-
111
- * Search in your WordPress plugins admin panel for “iubenda Cookie and Consent Solution”, install it;
112
- * Once the plugin is installed and activated, go to the Admin Panel → iubenda menu where you can select either the Cookie Solution or Consent Solution (depending on which you’d like to set up first).
113
- * **For the Cookie Solution**, you will be asked to paste your script into that field – the script is generated from your iubenda account dashboard when you activate the solution. For more information on how to activate the Cookie Solution, see this article (https://www.iubenda.com/en/help/1177-cookie-solution-getting-started#banner).
114
- * At this point the plugin will begin to show your banner on which displays the legal text, the consent options and your cookie policy (link) to users who visit the site for the first time. No need for other configurations;
115
- * Furthermore, the plugin automatically recognizes and blocks cookies that get installed via an extensive list of services such as the YouTube video player, social widgets (e.g the Facebook Like Box) etc. on your site. The full list is included in the “details” above.
116
- * Important note: Scripts can only be automatically blocked when generated from the server side (therefore processed by PHP via WordPress). Scripts that are added to the page via Javascript after page load must be blocked manually. Thankfully, this is fairly easy to do via the Custom Scripts field in the plugin console. Simply enter the custom script or iframe sources you'd like to block within the field, and click on the save changes button. You can find details, examples and further information [here](https://www.iubenda.com/en/help/1215-cookie-solution-wordpress-plugin-installation-guide#blocking-custom-scripts).
117
- * If you’d like to manually block a specific script using a manual “wrap” method, you can use the following:
118
- `<!--IUB-COOKIE-BLOCK-START-->
119
- <iframe src="...
120
- <img src="...
121
- <!--IUB-COOKIE-BLOCK-END-->`
122
- * For elements installed directly within WordPress posts (as opposed to elements integrated at the template level – example footer.php) there are shortcodes available:
123
- `[iub-cookie-policy]
124
- [/iub-cookie-policy]`
125
- * In case you’re querying WordPress via API, you can disable our plugin by using the iub_no_parse=true URL parameter, like this: www.example.com/api/get_recent_posts?iub_no_parse=true (http://www.example.com/api/get_recent_posts?iub_no_parse=true).
126
- * **For the Consent Solution**, you will need to paste in your Consent Solution API key. Once you’ve activated the Consent Solution in your iubenda dashboard, you can find your public API key in your dashboard (https://www.iubenda.com/en/dashboard) at [Your website] > Consent Solution > Embed).
127
-
128
- == Frequently Asked Questions ==
129
-
130
- **Where can I find help?**
131
- You can find a dedicated support forum thread here [Uservoice forum](https://support.iubenda.com/support/discussions/forums/42000118028) or we're happy to answer at info@iubenda.com.
132
-
133
- **Do you have more guidance, or a demo?**
134
- Here’s a [quick video](https://iubenda.wistia.com/medias/02ie8av6kt) on what the cookie banner looks like and how you can configure it. More details on how to fully set up the Cookie Solution for wordpress [here](https://www.iubenda.com/en/help/1215-cookie-solution-wordpress-plugin-installation-guide).
135
-
136
- Here’s a [quick look](https://iubenda.wistia.com/medias/fsbr465bku) at the Consent Solution dashboard. More details on how to fully set up the Consent Solution for wordpress [here](https://www.iubenda.com/en/help/13083-consent-solution-wordpress-contact-form-7) .
137
-
138
- **Bug reports**
139
- The best way you can help us is by providing as much information as possible, including the use of [wp_debug](https://wordpress.org/support/article/debugging-in-wordpress/).
140
- We will be very happy to receive feedback here: [Uservoice forum](https://support.iubenda.com/support/discussions/forums/42000115771)
141
-
142
- == Screenshots ==
143
-
144
- 1. It's as simple as copy-pasting the code from iubenda into the plugin form.
145
- 2. Simply enter you API key and click on autodetect to see all forms eligible for mapping.
146
- 3. The visual configurator lets you fully customize the look and feel of your banner, wording, and consent collection options.
147
- 4. When clicking on the cookie policy link, the user gets a view of the entire cookie policy, where they ultimately can give their consent.
148
- 5. IAB Transparency and consent framework integrated.
149
- 6. IAB Transparency and consent framework integrated.
150
-
151
- == Changelog ==
152
-
153
- = 2.3.2 =
154
- * Fix: Configuration regular expression issue in some edge cases
155
-
156
- = 2.3.1 =
157
- * Fix: Error on AMP configuration during install in some edge cases
158
- * Fix: Invalid www detection during AMP configuration generation process
159
- * Fix: Regex for iubenda script url in AMP configuration
160
- * Tweak: Added noindex for generated AMP configuration file
161
-
162
- = 2.3.0 =
163
- * Fix: Multiple consent forms per page support
164
- * Fix: WP Forms checkbox field compatibility
165
- * Tweak: AMP consent geolocation support
166
-
167
- = 2.2.0 =
168
- * Fix: Undefined notice during plugin update
169
-
170
- = 2.1.0 =
171
- * New: Per-purpose script blocking support
172
- * New: "Reject" button support
173
- * New: Google AMP compatibility option
174
- * Tweak: Improved regular expression on per-purpose feature detection
175
- * Fix: Safari unrecognized expression on CSS wildcards
176
-
177
- = 2.1.4-beta =
178
- * New: Multilingual support from AMP
179
-
180
- = 2.1.3-beta =
181
- * Tweak: Block tracking code from WP AMP plugins
182
-
183
- = 2.1.2-beta =
184
- * New: Google AMP compatibility option
185
-
186
- = 2.1.1-beta =
187
- * Tweak: Improved regular expression on per-purpose feature detection
188
- * Fix: Safari unrecognized expression on CSS wildcards
189
-
190
- = 2.1.0-beta =
191
- * New: Per-purpose script blocking support
192
- * New: "Reject" button support
193
-
194
- = 2.0.2 =
195
- * Fix: initialize iubenda CS on POST requests not working
196
- * Tweak: iubenda generic menu icon switched to iubenda logo
197
-
198
- = 2.0.1 =
199
- * New: Jetpack tracking blocking support
200
- * Fix: add_submenu_page and add_menu_page called incorrectly in WP 5.3
201
-
202
- = 2.0.0 =
203
- * New: Introducing iubenda Consent Solution integration
204
- * Tweak: Simple HTML Dom update to 1.9
205
-
206
- = 2.0.3-beta =
207
- * New: Introducing WooCommerce checkout form field mapping compatibility
208
-
209
- = 2.0.2-beta =
210
- * New: Introducing wildcard support for scripts and iframes
211
-
212
- = 2.0.1-beta =
213
- * New: Option to initialize iubenda CS on POST requests
214
- * Tweak: Update Cookie Solution and Consent Solution copy
215
-
216
- = 2.0-beta =
217
- * New: Introducing iubenda Consent Solution integration
218
- * Tweak: Simple HTML Dom update to 1.9
219
-
220
- = 1.15.8 =
221
- * New: Introducing a way to skip specific script parsing
222
- * Fix: Google ReCaptcha with Contact Form 7 initialization issue
223
- * Fix: Improved handling of iubenda script HTML
224
- * Tweak: Support links update
225
-
226
- = 1.15.7 =
227
- * Fix: Google ReCaptcha loading issue with Contact Form 7
228
- * Tweak: Improved Youtube and Google Maps script blocking
229
-
230
- = 1.15.6 =
231
- * Fix: iubenda script tags removed when Jetpack is active
232
-
233
- = 1.15.5 =
234
- * Fix: Skip parsing engine when scripts blocking is disabled
235
- * Tweak: Update iubenda logo
236
-
237
- = 1.15.4 =
238
- * New: Option to block custom scripts and iframes
239
- * Tweak: Update and extend the list of blocked scripts including Google Site Search, Google oAuth, Linkedin widgets, PayPal widgets, Freshchat, Uservoice
240
- , AdRoll, Olark, Segment, Kissmetrics, Mixpanel, Pingdom, Bing and Elevio
241
-
242
- = 1.15.3 =
243
- * Tweak: Update and extend the list of blocked scripts including Pinterest, AddThis, Disqus, Optimizely, Neodata, Criteo, Outbrain, Headway and Codepen
244
-
245
- = 1.15.2 =
246
- * Tweak: Update and unify iubenda parsing engine
247
- * Tweak: Polylang Pro support
248
-
249
- = 1.15.1 =
250
- * Fix: iubenda code field removing HTML tags on save
251
- * Tweak: Adjusted the script blocking regex in shortcode
252
-
253
- = 1.15.0 =
254
- * New: Option to select iubenda menu position
255
- * Tweak: iubenda faster class regex update
256
- * Tweak: Enable style tag in iubenda code field
257
- * Tweak: Changed default parser method
258
-
259
- = 1.14.2 =
260
- * New: iubenda_initial_output filter hook
261
-
262
- = 1.14.2-beta1 =
263
- * Fix: repository issues breaking the update
264
-
265
- = 1.14.1 =
266
- * New: Option to delete all plugin data upon deactivation
267
- * Fix: Code script attributes stripped from default code block
268
- * Fix: Updated plugin help links
269
- * Fix: Italian language files not loading properly
270
-
271
- = 1.14.0 =
272
- * New: i18 support
273
- * New: Polylang support
274
- * Fix: Multiple classes no longer being added to script tags
275
- * Fix: Buffering action hooks adjustments
276
- * General rewrite using WordPress coding standards
277
- * Turned into OOP
278
-
279
- = 1.11.1 =
280
- * New: Created a new option that disables the plugin on RSS feeds
281
- * New: Improved the control that checks if the request content type is HTML
282
- * Fixed an issue with the banner script
283
- * Fixed a series of conflicts with UTF-8 special characters caused by the experimental parsing engine
284
-
285
- = 1.11.0 =
286
- * New: Introduced a MUCH FASTER experimental parsing engine (visit the plugin options and select the experimental parsing engine)
287
- * New: Created a new option that allow users to enable/disable the parsing engine and to select the parsing engine between stable and experimental
288
- * New: Created a new option that filters the output buffer level to get only the first level ()
289
- * Fixed a series of conflicts with AJAX requests, which were conflicting with Contact Form 7, BackWPUp and other plugins
290
- * Added filter that only activates the plugin when the Content Type is text/html, enabled by default
291
- * Loads of bug fixes and speed improvements
292
-
293
- = 1.10.21 =
294
- * Rolling back to 1.10.11
295
-
296
- = 1.10.20 =
297
- * Hotfix: moved "is_user_logged_in" method control after the “template_redirect” hook.
298
-
299
- = 1.10.19 =
300
- * Fixed a series of conflicts with AJAX requests, which were conflicting with Contact Form 7 and other plugins
301
-
302
- = 1.10.18 =
303
- * More bugs fixed
304
- * The content-type restriction option is now on by default
305
-
306
- = 1.10.17 =
307
- * Added filter that only activates the plugin when the Content Type is text/html
308
- * Loads of bug fixes and speed improvements
309
-
310
- = 1.10.11 =
311
- * iub_no_parse parameter reintroduced
312
- * added XMLRPC control
313
-
314
- = 1.10.10 =
315
- * French and Portuguese languages fixed when used with WPML
316
-
317
- = 1.10.9 =
318
- * Further bugfixing
319
-
320
- = 1.10.9 =
321
- * Further bugfixing
322
-
323
- = 1.10.8 =
324
- * Fixed problems with WPML and with using the shortcode
325
-
326
- = 1.10.7 =
327
- * Further work on resolving any conflicts with other plugins
328
- * Fixed a problem with the Media library
329
-
330
- = 1.10.5 =
331
- * Reverting the parsing method to 1.9.19, slower but more stable
332
-
333
- = 1.10.4 =
334
- * Fixed compatibility with the Yoast SEO plugin (and possibly others)
335
- * Fixed preference saving after update from 1.9.19
336
-
337
- = 1.10.3 =
338
- * Fixed the WPML activation, which now detects the language of the embedding code and places it in the right tab
339
- * The first tab when WPML is activated is now activated automatically
340
- * The iubenda shortcode has been improved to be more flexible
341
-
342
- = 1.10.2 =
343
- * Fixed an encoding issue
344
-
345
- = 1.10.1 =
346
- * Fixed a bug that forced users to re-insert their cookie law code
347
-
348
- = 1.10.0 =
349
- * New: Multi-language support with WPML integration
350
- * New: AdSense auto-matching/blocking has been redone and now works properly
351
- * New: Addthis and Sharethis are now also automatically blocked
352
- * Loads of small fixes and improvements
353
-
354
- = 1.9.28 =
355
- * Fixed some bugs about i18n, created .pot files for translations. Now is true i18n friendly. Tested.
356
-
357
- = 1.9.27 =
358
- * i18n friendly
359
-
360
- = 1.9.26 =
361
- * Associate cookie policy for installation before/after WPML
362
-
363
- = 1.9.25 =
364
- * Hiding E_NOTICE messages
365
-
366
- = 1.9.24 =
367
- * skip parsing if XML-RPC request
368
- * skip parsing if is admin page
369
- * added multilanguage
370
-
371
- = 1.9.19 =
372
- * new iframe src according to the new doc
373
-
374
- = 1.9.18 =
375
- * bug on all iframe, suppressedsrc is not null anymore
376
-
377
- = 1.9.17 =
378
- * added another url of google maps embed
379
-
380
- = 1.9.16 =
381
- * skip parsing page if bot/crawler + added checkbox to autoparse (or not) the page if the user have already given the consent
382
-
383
- = 1.9.15 =
384
- * include bug + google maps
385
-
386
- = 1.9.14 =
387
- * Autoconvert iframe vimeo + facebook likebox
388
-
389
- = 1.9.13 =
390
- * Now the plugin use iubenda.class.php + fix bug on it.
391
-
392
- = 1.9.12 =
393
- * Add iub__no_parse get parameter to skip parsing page
394
-
395
- = 1.9.11 =
396
- * Add iub__no_parse get parameter to skip parsing page
397
-
398
- = 1.9.10 =
399
- * Another adsense script blocked, another fix on simple html dom
400
-
401
- = 1.9.9 =
402
- * Bugs page 60000 chars
403
-
404
- = 1.9.8 =
405
- * Added Google Maps & Google Adsense + better shortcode handling
406
-
407
- = 1.9.7 =
408
- * minor bugfix
409
-
410
- = 1.9.6 =
411
- * bugfix: custom banner now allowed
412
-
413
- = 1.9.5 =
414
- * no refresh page needed to activate scripts inside IUB tags.
415
-
416
- = 1.9.4 =
417
- * wp-admin blank page bug fix
418
-
419
- = 1.9.3 =
420
- * G+ platform bug, typo: _iub_cs_activate_inline vs _iub_cs_activate-inline
421
-
422
- = 1.9.2 =
423
- * G+ platform bug
424
-
425
- = 1.9.1 =
426
- * Minor improvements
427
-
428
- = 1.9 =
429
- * Improved parsing without regex
430
- * No parsing if the user have already given the consent
431
-
432
- = 1.0 =
433
- * First plugin version.
434
-
435
- == Upgrade Notice ==
436
-
437
- = 2.3.2 =
438
- * Fix: Configuration regular expression issue in some edge cases
 
 
 
1
+ === iubenda - Cookie and Consent Solution for the GDPR & ePrivacy ===
2
+ Contributors: iubenda
3
+ Donate link:
4
+ Tags: cookies, cookie law, cookie policy, cookie banner, privacy policy, cookie consent, privacy, gdpr, eprivacy
5
+ Requires at least: 4.0
6
+ Requires PHP: 5.2.4
7
+ Tested up to: 5.3.2
8
+ Stable tag: 2.3.3
9
+ License: MIT License
10
+ License URI: http://opensource.org/licenses/MIT
11
+
12
+ 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.
13
+
14
+ == Description ==
15
+
16
+ This plugin is an All-in-One approach developed by iubenda, which includes functionalities of two powerful solutions (see below) that help to make your website GDPR and ePrivacy compliant. The plugin lets you automate the implementation of ePrivacy (Cookie Law) and GDPR requirements by providing a fully customizable cookie banner, blocking scripts, and by managing all aspects of cookie consent. It also allows you to record, review, and maintain comprehensive GDPR records of consent for your web-forms.
17
+
18
+ == Cookie Solution ==
19
+
20
+ This plugin drastically reduces the need for direct interventions in the code of the site by integrating with iubenda’s Cookie Solution. It provides a fully customizable cookie banner, dynamically generates a cookie policy to [match the services in use on your site](https://www.iubenda.com/en/help/19004-how-to-use-the-site-scanner-from-within-the-generator), and, fully manages cookie-related consent – including the blocking of the most common widgets and third-party cookies before consent is received – in order to comply with the GDPR and ePrivacy.
21
+
22
+ **Key features:**
23
+
24
+ * The plugin automatically inserts the iubenda code in the head of every page of the site
25
+ * Allows you to automatically or manually block scripts that can install cookies prior to consent, without the need of direct intervention on the code
26
+ * Allows you to autodetect and limit prior-blocking and cookie consent requests only to users from the EU – where this is a legal requirement – while running cookies scripts normally in regions where you are still legally allowed to do so.
27
+ * Asynchronously re-activates cookie scripts once consent is collected.
28
+ * Handles the display of the cookie banner and cookie policy, allowing you to fully customize the banner to match the look and colors of your site if needed
29
+ * California Consumer Privacy Act [(CCPA) Support](https://www.iubenda.com/en/help/21165-ccpa-how-to-add-a-notice-of-collection-and-a-do-not-sell-link)
30
+ * Saves user preferences about the use of cookies and displays a clean page (without banner) to users who have already provided their consent
31
+ * Integrates with IAB’s [Transparency and Consent Framework](https://www.iubenda.com/en/help/7440-enable-preference-management-iab-framework#revenue) (TCF)
32
+ * Allows you to provide you users with granular, per-category preference control (e.g. basic functionalities, experience enhancement, targeting & advertising)
33
+ * Compatible with Google's Accelerated Mobile Pages (AMP)
34
+ * Features an easy-to-use interface for entering custom scripts and iframes
35
+ * Detects bots/spiders and serves them a clean page so that your SEO efforts are never compromised
36
+
37
+ **The plugin is currently capable of automatically detecting and blocking the following scripts:**
38
+
39
+ * Google Analytics
40
+ * Google Maps
41
+ * Google AdSense
42
+ * Google ReCaptcha
43
+ * Google Site Search
44
+ * Google Tag Manager
45
+ * Google oAuth
46
+ * Google+ widgets
47
+ * Twitter widgets
48
+ * Facebook widgets
49
+ * Facebook Comments
50
+ * YouTube
51
+ * Vimeo
52
+ * Linkedin widgets
53
+ * ShareThis widgets
54
+ * Instagram widgets
55
+ * AddThis widgets
56
+ * Pinterest widgets
57
+ * PayPal widgets
58
+ * Disqus
59
+ * Optimizely
60
+ * Neodata
61
+ * Criteo
62
+ * Outbrain
63
+ * Headway
64
+ * Codepen
65
+ * Freshchat
66
+ * Uservoice
67
+ * AdRoll
68
+ * Olark
69
+ * Segment
70
+ * Kissmetrics
71
+ * Mixpanel
72
+ * Pingdom
73
+ * Bing
74
+ * Elevio
75
+
76
+ == Consent Solution ==
77
+
78
+ Maintaining valid records of consent is a vital part of privacy compliance in general, and it is specifically required under the GDPR. These records should include a userid, timestamp, consent proof, record of the consenting action, and the legal documents available to the user at the time of consent, among other things. This plugin **is THE most complete solution for recording, sorting and maintaining GDPR records of consent**. The plugin also boasts built-in compatibility with WordPress comment form, Contact Form 7 and WP Forms plugins for your convenience, but can be manually integrated with any type of web-form and can even store consent proofs for consents collected offline (e.g in-store sign-ups) via WP media upload.
79
+
80
+ **Key features:**
81
+
82
+ * The plugin detects and identifies all supported forms that are embedded in the website
83
+ * It’s auto-compatible with and allows super easy mapping of Contact Form 7, WP Forms, WordPress comment and WooCommerce checkout forms
84
+ * It allows manual integration with any type of web-form
85
+ * For each consent, track the form/wording the user was prompted with
86
+ * Flexibly upload any form of proof of consent or legal notice, including a PDF if consent was collected offline
87
+ * It provides a high granularity: map individual form fields, exclude fields (like password inputs), add legal notices available at the time of consent collection, indicate double opt-in, set preferences and more
88
+ * REST HTTP API and JS SDK, to give you total control and how and when consent is stored
89
+ * Store multiple preferences for each user (e.g. if you have multiple newsletters or opt-ins)
90
+ * Features an easy-to-use interface for entering custom scripts and iframes
91
+ * It provides API input field for quick and easy activation
92
+
93
+ **Some background information**
94
+
95
+ If you potentially have any European users, you must comply with laws like the [GDPR](https://www.iubenda.com/en/help/5428-gdpr-guide#consent) and [ePrivacy](https://www.iubenda.com/en/help/6293-cookie-consent-management-faq). These laws are precise in their requirements and technical implementation can be pretty complicated. We've tried to make this process as painless as possible for website and app owners with our suite of compliance software solutions.
96
+ Our Cookie and Consent Solution plugin for WordPress simplifies and manages these compliance requirements within a few clicks. This extension works with the iubenda [Cookie Solution](https://www.iubenda.com/en/cookie-solution) and [Consent Solution](https://www.iubenda.com/en/consent-solution).
97
+
98
+ **Which languages does iubenda work in currently?**
99
+
100
+ * English
101
+ * Italian
102
+ * French
103
+ * Spanish
104
+ * Portuguese (Brazilian)
105
+ * German
106
+ * Dutch
107
+ * Russian
108
+
109
+ == Installation ==
110
+
111
+ * Search in your WordPress plugins admin panel for “iubenda Cookie and Consent Solution”, install it;
112
+ * Once the plugin is installed and activated, go to the Admin Panel → iubenda menu where you can select either the Cookie Solution or Consent Solution (depending on which you’d like to set up first).
113
+ * **For the Cookie Solution**, you will be asked to paste your script into that field – the script is generated from your iubenda account dashboard when you activate the solution. For more information on how to activate the Cookie Solution, see this article (https://www.iubenda.com/en/help/1177-cookie-solution-getting-started#banner).
114
+ * At this point the plugin will begin to show your banner on which displays the legal text, the consent options and your cookie policy (link) to users who visit the site for the first time. No need for other configurations;
115
+ * Furthermore, the plugin automatically recognizes and blocks cookies that get installed via an extensive list of services such as the YouTube video player, social widgets (e.g the Facebook Like Box) etc. on your site. The full list is included in the “details” above.
116
+ * Important note: Scripts can only be automatically blocked when generated from the server side (therefore processed by PHP via WordPress). Scripts that are added to the page via Javascript after page load must be blocked manually. Thankfully, this is fairly easy to do via the Custom Scripts field in the plugin console. Simply enter the custom script or iframe sources you'd like to block within the field, and click on the save changes button. You can find details, examples and further information [here](https://www.iubenda.com/en/help/1215-cookie-solution-wordpress-plugin-installation-guide#blocking-custom-scripts).
117
+ * If you’d like to manually block a specific script using a manual “wrap” method, you can use the following:
118
+ `<!--IUB-COOKIE-BLOCK-START-->
119
+ <iframe src="...
120
+ <img src="...
121
+ <!--IUB-COOKIE-BLOCK-END-->`
122
+ * For elements installed directly within WordPress posts (as opposed to elements integrated at the template level – example footer.php) there are shortcodes available:
123
+ `[iub-cookie-policy]
124
+ [/iub-cookie-policy]`
125
+ * In case you’re querying WordPress via API, you can disable our plugin by using the iub_no_parse=true URL parameter, like this: www.example.com/api/get_recent_posts?iub_no_parse=true (http://www.example.com/api/get_recent_posts?iub_no_parse=true).
126
+ * **For the Consent Solution**, you will need to paste in your Consent Solution API key. Once you’ve activated the Consent Solution in your iubenda dashboard, you can find your public API key in your dashboard (https://www.iubenda.com/en/dashboard) at [Your website] > Consent Solution > Embed).
127
+
128
+ == Frequently Asked Questions ==
129
+
130
+ **Where can I find help?**
131
+ You can find a dedicated support forum thread here [Uservoice forum](https://support.iubenda.com/support/discussions/forums/42000118028) or we're happy to answer at info@iubenda.com.
132
+
133
+ **Do you have more guidance, or a demo?**
134
+ Here’s a [quick video](https://iubenda.wistia.com/medias/02ie8av6kt) on what the cookie banner looks like and how you can configure it. More details on how to fully set up the Cookie Solution for wordpress [here](https://www.iubenda.com/en/help/1215-cookie-solution-wordpress-plugin-installation-guide).
135
+
136
+ Here’s a [quick look](https://iubenda.wistia.com/medias/fsbr465bku) at the Consent Solution dashboard. More details on how to fully set up the Consent Solution for wordpress [here](https://www.iubenda.com/en/help/13083-consent-solution-wordpress-contact-form-7) .
137
+
138
+ **Bug reports**
139
+ The best way you can help us is by providing as much information as possible, including the use of [wp_debug](https://wordpress.org/support/article/debugging-in-wordpress/).
140
+ We will be very happy to receive feedback here: [Uservoice forum](https://support.iubenda.com/support/discussions/forums/42000115771)
141
+
142
+ == Screenshots ==
143
+
144
+ 1. It's as simple as copy-pasting the code from iubenda into the plugin form.
145
+ 2. Simply enter you API key and click on autodetect to see all forms eligible for mapping.
146
+ 3. The visual configurator lets you fully customize the look and feel of your banner, wording, and consent collection options.
147
+ 4. When clicking on the cookie policy link, the user gets a view of the entire cookie policy, where they ultimately can give their consent.
148
+ 5. IAB Transparency and consent framework integrated.
149
+ 6. IAB Transparency and consent framework integrated.
150
+
151
+ == Changelog ==
152
+
153
+ = 2.3.3 =
154
+ * Fix: AddThis purpose category
155
+
156
+ = 2.3.2 =
157
+ * Fix: Configuration regular expression issue in some edge cases
158
+
159
+ = 2.3.1 =
160
+ * Fix: Error on AMP configuration during install in some edge cases
161
+ * Fix: Invalid www detection during AMP configuration generation process
162
+ * Fix: Regex for iubenda script url in AMP configuration
163
+ * Tweak: Added noindex for generated AMP configuration file
164
+
165
+ = 2.3.0 =
166
+ * Fix: Multiple consent forms per page support
167
+ * Fix: WP Forms checkbox field compatibility
168
+ * Tweak: AMP consent geolocation support
169
+
170
+ = 2.2.0 =
171
+ * Fix: Undefined notice during plugin update
172
+
173
+ = 2.1.0 =
174
+ * New: Per-purpose script blocking support
175
+ * New: "Reject" button support
176
+ * New: Google AMP compatibility option
177
+ * Tweak: Improved regular expression on per-purpose feature detection
178
+ * Fix: Safari unrecognized expression on CSS wildcards
179
+
180
+ = 2.1.4-beta =
181
+ * New: Multilingual support from AMP
182
+
183
+ = 2.1.3-beta =
184
+ * Tweak: Block tracking code from WP AMP plugins
185
+
186
+ = 2.1.2-beta =
187
+ * New: Google AMP compatibility option
188
+
189
+ = 2.1.1-beta =
190
+ * Tweak: Improved regular expression on per-purpose feature detection
191
+ * Fix: Safari unrecognized expression on CSS wildcards
192
+
193
+ = 2.1.0-beta =
194
+ * New: Per-purpose script blocking support
195
+ * New: "Reject" button support
196
+
197
+ = 2.0.2 =
198
+ * Fix: initialize iubenda CS on POST requests not working
199
+ * Tweak: iubenda generic menu icon switched to iubenda logo
200
+
201
+ = 2.0.1 =
202
+ * New: Jetpack tracking blocking support
203
+ * Fix: add_submenu_page and add_menu_page called incorrectly in WP 5.3
204
+
205
+ = 2.0.0 =
206
+ * New: Introducing iubenda Consent Solution integration
207
+ * Tweak: Simple HTML Dom update to 1.9
208
+
209
+ = 2.0.3-beta =
210
+ * New: Introducing WooCommerce checkout form field mapping compatibility
211
+
212
+ = 2.0.2-beta =
213
+ * New: Introducing wildcard support for scripts and iframes
214
+
215
+ = 2.0.1-beta =
216
+ * New: Option to initialize iubenda CS on POST requests
217
+ * Tweak: Update Cookie Solution and Consent Solution copy
218
+
219
+ = 2.0-beta =
220
+ * New: Introducing iubenda Consent Solution integration
221
+ * Tweak: Simple HTML Dom update to 1.9
222
+
223
+ = 1.15.8 =
224
+ * New: Introducing a way to skip specific script parsing
225
+ * Fix: Google ReCaptcha with Contact Form 7 initialization issue
226
+ * Fix: Improved handling of iubenda script HTML
227
+ * Tweak: Support links update
228
+
229
+ = 1.15.7 =
230
+ * Fix: Google ReCaptcha loading issue with Contact Form 7
231
+ * Tweak: Improved Youtube and Google Maps script blocking
232
+
233
+ = 1.15.6 =
234
+ * Fix: iubenda script tags removed when Jetpack is active
235
+
236
+ = 1.15.5 =
237
+ * Fix: Skip parsing engine when scripts blocking is disabled
238
+ * Tweak: Update iubenda logo
239
+
240
+ = 1.15.4 =
241
+ * New: Option to block custom scripts and iframes
242
+ * Tweak: Update and extend the list of blocked scripts including Google Site Search, Google oAuth, Linkedin widgets, PayPal widgets, Freshchat, Uservoice
243
+ , AdRoll, Olark, Segment, Kissmetrics, Mixpanel, Pingdom, Bing and Elevio
244
+
245
+ = 1.15.3 =
246
+ * Tweak: Update and extend the list of blocked scripts including Pinterest, AddThis, Disqus, Optimizely, Neodata, Criteo, Outbrain, Headway and Codepen
247
+
248
+ = 1.15.2 =
249
+ * Tweak: Update and unify iubenda parsing engine
250
+ * Tweak: Polylang Pro support
251
+
252
+ = 1.15.1 =
253
+ * Fix: iubenda code field removing HTML tags on save
254
+ * Tweak: Adjusted the script blocking regex in shortcode
255
+
256
+ = 1.15.0 =
257
+ * New: Option to select iubenda menu position
258
+ * Tweak: iubenda faster class regex update
259
+ * Tweak: Enable style tag in iubenda code field
260
+ * Tweak: Changed default parser method
261
+
262
+ = 1.14.2 =
263
+ * New: iubenda_initial_output filter hook
264
+
265
+ = 1.14.2-beta1 =
266
+ * Fix: repository issues breaking the update
267
+
268
+ = 1.14.1 =
269
+ * New: Option to delete all plugin data upon deactivation
270
+ * Fix: Code script attributes stripped from default code block
271
+ * Fix: Updated plugin help links
272
+ * Fix: Italian language files not loading properly
273
+
274
+ = 1.14.0 =
275
+ * New: i18 support
276
+ * New: Polylang support
277
+ * Fix: Multiple classes no longer being added to script tags
278
+ * Fix: Buffering action hooks adjustments
279
+ * General rewrite using WordPress coding standards
280
+ * Turned into OOP
281
+
282
+ = 1.11.1 =
283
+ * New: Created a new option that disables the plugin on RSS feeds
284
+ * New: Improved the control that checks if the request content type is HTML
285
+ * Fixed an issue with the banner script
286
+ * Fixed a series of conflicts with UTF-8 special characters caused by the experimental parsing engine
287
+
288
+ = 1.11.0 =
289
+ * New: Introduced a MUCH FASTER experimental parsing engine (visit the plugin options and select the experimental parsing engine)
290
+ * New: Created a new option that allow users to enable/disable the parsing engine and to select the parsing engine between stable and experimental
291
+ * New: Created a new option that filters the output buffer level to get only the first level ()
292
+ * Fixed a series of conflicts with AJAX requests, which were conflicting with Contact Form 7, BackWPUp and other plugins
293
+ * Added filter that only activates the plugin when the Content Type is text/html, enabled by default
294
+ * Loads of bug fixes and speed improvements
295
+
296
+ = 1.10.21 =
297
+ * Rolling back to 1.10.11
298
+
299
+ = 1.10.20 =
300
+ * Hotfix: moved "is_user_logged_in" method control after the “template_redirect” hook.
301
+
302
+ = 1.10.19 =
303
+ * Fixed a series of conflicts with AJAX requests, which were conflicting with Contact Form 7 and other plugins
304
+
305
+ = 1.10.18 =
306
+ * More bugs fixed
307
+ * The content-type restriction option is now on by default
308
+
309
+ = 1.10.17 =
310
+ * Added filter that only activates the plugin when the Content Type is text/html
311
+ * Loads of bug fixes and speed improvements
312
+
313
+ = 1.10.11 =
314
+ * iub_no_parse parameter reintroduced
315
+ * added XMLRPC control
316
+
317
+ = 1.10.10 =
318
+ * French and Portuguese languages fixed when used with WPML
319
+
320
+ = 1.10.9 =
321
+ * Further bugfixing
322
+
323
+ = 1.10.9 =
324
+ * Further bugfixing
325
+
326
+ = 1.10.8 =
327
+ * Fixed problems with WPML and with using the shortcode
328
+
329
+ = 1.10.7 =
330
+ * Further work on resolving any conflicts with other plugins
331
+ * Fixed a problem with the Media library
332
+
333
+ = 1.10.5 =
334
+ * Reverting the parsing method to 1.9.19, slower but more stable
335
+
336
+ = 1.10.4 =
337
+ * Fixed compatibility with the Yoast SEO plugin (and possibly others)
338
+ * Fixed preference saving after update from 1.9.19
339
+
340
+ = 1.10.3 =
341
+ * Fixed the WPML activation, which now detects the language of the embedding code and places it in the right tab
342
+ * The first tab when WPML is activated is now activated automatically
343
+ * The iubenda shortcode has been improved to be more flexible
344
+
345
+ = 1.10.2 =
346
+ * Fixed an encoding issue
347
+
348
+ = 1.10.1 =
349
+ * Fixed a bug that forced users to re-insert their cookie law code
350
+
351
+ = 1.10.0 =
352
+ * New: Multi-language support with WPML integration
353
+ * New: AdSense auto-matching/blocking has been redone and now works properly
354
+ * New: Addthis and Sharethis are now also automatically blocked
355
+ * Loads of small fixes and improvements
356
+
357
+ = 1.9.28 =
358
+ * Fixed some bugs about i18n, created .pot files for translations. Now is true i18n friendly. Tested.
359
+
360
+ = 1.9.27 =
361
+ * i18n friendly
362
+
363
+ = 1.9.26 =
364
+ * Associate cookie policy for installation before/after WPML
365
+
366
+ = 1.9.25 =
367
+ * Hiding E_NOTICE messages
368
+
369
+ = 1.9.24 =
370
+ * skip parsing if XML-RPC request
371
+ * skip parsing if is admin page
372
+ * added multilanguage
373
+
374
+ = 1.9.19 =
375
+ * new iframe src according to the new doc
376
+
377
+ = 1.9.18 =
378
+ * bug on all iframe, suppressedsrc is not null anymore
379
+
380
+ = 1.9.17 =
381
+ * added another url of google maps embed
382
+
383
+ = 1.9.16 =
384
+ * skip parsing page if bot/crawler + added checkbox to autoparse (or not) the page if the user have already given the consent
385
+
386
+ = 1.9.15 =
387
+ * include bug + google maps
388
+
389
+ = 1.9.14 =
390
+ * Autoconvert iframe vimeo + facebook likebox
391
+
392
+ = 1.9.13 =
393
+ * Now the plugin use iubenda.class.php + fix bug on it.
394
+
395
+ = 1.9.12 =
396
+ * Add iub__no_parse get parameter to skip parsing page
397
+
398
+ = 1.9.11 =
399
+ * Add iub__no_parse get parameter to skip parsing page
400
+
401
+ = 1.9.10 =
402
+ * Another adsense script blocked, another fix on simple html dom
403
+
404
+ = 1.9.9 =
405
+ * Bugs page 60000 chars
406
+
407
+ = 1.9.8 =
408
+ * Added Google Maps & Google Adsense + better shortcode handling
409
+
410
+ = 1.9.7 =
411
+ * minor bugfix
412
+
413
+ = 1.9.6 =
414
+ * bugfix: custom banner now allowed
415
+
416
+ = 1.9.5 =
417
+ * no refresh page needed to activate scripts inside IUB tags.
418
+
419
+ = 1.9.4 =
420
+ * wp-admin blank page bug fix
421
+
422
+ = 1.9.3 =
423
+ * G+ platform bug, typo: _iub_cs_activate_inline vs _iub_cs_activate-inline
424
+
425
+ = 1.9.2 =
426
+ * G+ platform bug
427
+
428
+ = 1.9.1 =
429
+ * Minor improvements
430
+
431
+ = 1.9 =
432
+ * Improved parsing without regex
433
+ * No parsing if the user have already given the consent
434
+
435
+ = 1.0 =
436
+ * First plugin version.
437
+
438
+ == Upgrade Notice ==
439
+
440
+ = 2.3.3 =
441
+ * Fix: AddThis purpose category