iubenda Cookie Solution for GDPR - Version 2.3.4

Version Description

  • Security Fix: limit url sanitize to http protocols
Download this release

Release Info

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

Code changes from version 2.3.3 to 2.3.4

iubenda-cookie-class/README.md CHANGED
@@ -1,8 +1,8 @@
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).
@@ -16,7 +16,7 @@ The iubenda Cookie Solution is an all-in-one approach developed by iubenda, that
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
 
@@ -88,16 +88,19 @@ Simply copy your method into the PHP document and then call it with the followin
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
 
@@ -132,4 +135,4 @@ These operations take place in accordance with the rules explained in [this guid
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).
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
 
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.1
102
+ * Fix: AddThis per-purpose category
103
+
104
  ##### 4.1.0
105
  * New: Google AMP support
106
 
135
 
136
  ### License
137
 
138
+ This project is licensed under the GPl 3 license.
iubenda-cookie-class/iubenda.class.faster.php CHANGED
@@ -1,13 +1,13 @@
1
  <?php
2
  /**
3
  * iubenda.class.faster.php
4
- *
5
  * @author iubenda s.r.l
6
- * @copyright 2018-2019, iubenda s.r.l
7
  * @license GNU/GPL
8
  * @version 2.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
@@ -23,7 +23,7 @@
23
  */
24
 
25
  class iubendaFaster {
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';
@@ -63,7 +63,7 @@ class iubendaFaster {
63
 
64
  /**
65
  * Methods
66
- *
67
  * @param type $offender
68
  * @param type $blacklist
69
  * @return boolean
@@ -86,9 +86,9 @@ class iubendaFaster {
86
  }
87
 
88
  /**
89
- * Parse automatically all the scripts in the page and converts it in text/plain
90
  * if src or the whole output has inside one of the elements in $auto_script_tags array
91
- *
92
  * @param mixed $content
93
  * @return mixed
94
  */
@@ -149,7 +149,7 @@ class iubendaFaster {
149
 
150
  /**
151
  * Parse all IUBENDAs comment and convert the code inside with create_tags method
152
- *
153
  * @param mixed $content
154
  * @return mixed
155
  */
@@ -183,7 +183,7 @@ class iubendaFaster {
183
 
184
  /**
185
  * Convert scripts, iframe and other code inside IUBENDAs comment in text/plain to not generate cookies
186
- *
187
  * @param mixed $content
188
  * @return mixed
189
  */
@@ -224,4 +224,4 @@ class iubendaFaster {
224
  return $js;
225
  }
226
 
227
- }
1
  <?php
2
  /**
3
  * iubenda.class.faster.php
4
+ *
5
  * @author iubenda s.r.l
6
+ * @copyright 2018-2020, iubenda s.r.l
7
  * @license GNU/GPL
8
  * @version 2.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
23
  */
24
 
25
  class iubendaFaster {
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';
63
 
64
  /**
65
  * Methods
66
+ *
67
  * @param type $offender
68
  * @param type $blacklist
69
  * @return boolean
86
  }
87
 
88
  /**
89
+ * Parse automatically all the scripts in the page and converts it in text/plain
90
  * if src or the whole output has inside one of the elements in $auto_script_tags array
91
+ *
92
  * @param mixed $content
93
  * @return mixed
94
  */
149
 
150
  /**
151
  * Parse all IUBENDAs comment and convert the code inside with create_tags method
152
+ *
153
  * @param mixed $content
154
  * @return mixed
155
  */
183
 
184
  /**
185
  * Convert scripts, iframe and other code inside IUBENDAs comment in text/plain to not generate cookies
186
+ *
187
  * @param mixed $content
188
  * @return mixed
189
  */
224
  return $js;
225
  }
226
 
227
+ }
iubenda-cookie-class/iubenda.class.page.php CHANGED
@@ -1,13 +1,13 @@
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
@@ -61,7 +61,7 @@ class iubendaPage {
61
 
62
  /**
63
  * Construct: the whole HTML output of the page
64
- *
65
  * @param mixed $content_page
66
  */
67
  public function __construct( $content_page ) {
@@ -71,7 +71,7 @@ class iubendaPage {
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
  */
@@ -99,7 +99,7 @@ if('callback' in _iub.csConfiguration) {
99
 
100
  /**
101
  * Static, detect bot & crawler
102
- *
103
  * @return bool
104
  */
105
  static function bot_detected() {
@@ -108,7 +108,7 @@ if('callback' in _iub.csConfiguration) {
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() {
@@ -122,7 +122,7 @@ if('callback' in _iub.csConfiguration) {
122
 
123
  /**
124
  * Static, utility function: strpos for array
125
- *
126
  * @param type $haystack
127
  * @param type $needle
128
  * @return boolean
@@ -144,7 +144,7 @@ if('callback' in _iub.csConfiguration) {
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
  */
@@ -209,12 +209,12 @@ if('callback' in _iub.csConfiguration) {
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 ) ) {
@@ -340,7 +340,7 @@ if('callback' in _iub.csConfiguration) {
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 ) ) {
@@ -374,11 +374,11 @@ if('callback' in _iub.csConfiguration) {
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-2020, 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
61
 
62
  /**
63
  * Construct: the whole HTML output of the page
64
+ *
65
  * @param mixed $content_page
66
  */
67
  public function __construct( $content_page ) {
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
  */
99
 
100
  /**
101
  * Static, detect bot & crawler
102
+ *
103
  * @return bool
104
  */
105
  static function bot_detected() {
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() {
122
 
123
  /**
124
  * Static, utility function: strpos for array
125
+ *
126
  * @param type $haystack
127
  * @param type $needle
128
  * @return boolean
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
  */
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 ) ) {
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 ) ) {
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
@@ -5,7 +5,7 @@
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
5
  * @author iubenda s.r.l
6
  * @copyright 2018-2020, iubenda s.r.l
7
  * @license GNU/GPL
8
+ * @version 4.1.1
9
  * @deprecated
10
  *
11
  * This program is free software: you can redistribute it and/or modify
iubenda-cookie-class/test.php CHANGED
@@ -1,11 +1,11 @@
1
  <?php
2
  /**
3
  * test.php
4
- *
5
  * @author iubenda s.r.l
6
- * @copyright 2018-2019, iubenda s.r.l
7
  * @license GNU/GPL
8
- *
9
  * This program is free software: you can redistribute it and/or modify
10
  * it under the terms of the GNU General Public License as published by
11
  * the Free Software Foundation, either version 3 of the License, or
@@ -49,7 +49,9 @@ ini_set( 'max_execution_time', 300 );
49
 
50
  <?php
51
  if ( ! empty( $_POST['url'] ) )
52
- $url = filter_var( $_POST['url'], FILTER_SANITIZE_URL );
 
 
53
  else
54
  $url = '';
55
 
@@ -111,4 +113,4 @@ ini_set( 'max_execution_time', 300 );
111
  </div>
112
 
113
  </body>
114
- </html>
1
  <?php
2
  /**
3
  * test.php
4
+ *
5
  * @author iubenda s.r.l
6
+ * @copyright 2018-2020, iubenda s.r.l
7
  * @license GNU/GPL
8
+ *
9
  * This program is free software: you can redistribute it and/or modify
10
  * it under the terms of the GNU General Public License as published by
11
  * the Free Software Foundation, either version 3 of the License, or
49
 
50
  <?php
51
  if ( ! empty( $_POST['url'] ) )
52
+ if (substr($_POST['url'], 0, 4) == "http") {
53
+ $url = filter_var( $_POST['url'], FILTER_SANITIZE_URL );
54
+ }
55
  else
56
  $url = '';
57
 
113
  </div>
114
 
115
  </body>
116
+ </html>
iubenda-cookie-class/usage.php CHANGED
@@ -1,11 +1,11 @@
1
  <?php
2
  /**
3
  * usage.php
4
- *
5
  * @author iubenda s.r.l
6
- * @copyright 2018-2019, iubenda s.r.l
7
  * @license GNU/GPL
8
- *
9
  * This program is free software: you can redistribute it and/or modify
10
  * it under the terms of the GNU General Public License as published by
11
  * the Free Software Foundation, either version 3 of the License, or
@@ -43,4 +43,4 @@ function iubenda_system( $html, $type = 'page' ) {
43
  *
44
  * echo iubenda_system( "<html> ...content... </html>", 'faster' );
45
  *
46
- */
1
  <?php
2
  /**
3
  * usage.php
4
+ *
5
  * @author iubenda s.r.l
6
+ * @copyright 2018-2020, iubenda s.r.l
7
  * @license GNU/GPL
8
+ *
9
  * This program is free software: you can redistribute it and/or modify
10
  * it under the terms of the GNU General Public License as published by
11
  * the Free Software Foundation, either version 3 of the License, or
43
  *
44
  * echo iubenda_system( "<html> ...content... </html>", 'faster' );
45
  *
46
+ */
readme.txt CHANGED
@@ -150,6 +150,9 @@ We will be very happy to receive feedback here: [Uservoice forum](https://suppor
150
 
151
  == Changelog ==
152
 
 
 
 
153
  = 2.3.3 =
154
  * Fix: AddThis purpose category
155
 
150
 
151
  == Changelog ==
152
 
153
+ = 2.3.4 =
154
+ * Security Fix: limit url sanitize to http protocols
155
+
156
  = 2.3.3 =
157
  * Fix: AddThis purpose category
158
 
trunk/css/admin.css ADDED
@@ -0,0 +1,164 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #iubenda-header {
2
+ margin-bottom: 30px;
3
+ }
4
+ .iubenda-title {
5
+ margin-top: 10px;
6
+ font-weight: bold;
7
+ }
8
+ .iubenda-link {
9
+ display: table;
10
+ margin: 0 auto 10px;
11
+ }
12
+ .iubenda-text {
13
+ margin: 10px auto;
14
+ color: #434149
15
+ }
16
+ .button.button-primary.iub-autodetect-forms {
17
+ background: #1CC691;
18
+ border-color: #169970;
19
+ box-shadow: 0 1px 0 #138461;
20
+ text-shadow: 0 -1px 1px #138461,1px 0 1px #138461,0 1px 1px #138461,-1px 0 1px #138461;
21
+ display: inline-block;
22
+ margin-bottom: 30px;
23
+ }
24
+ .button.button-primary.iub-autodetect-forms:hover {
25
+ background: #1ACC94;
26
+ }
27
+ .button.button-primary.iub-autodetect-forms:focus {
28
+ box-shadow: 0 1px 0 #138461,0 0 2px 1px #1CC691;
29
+ }
30
+ #iubenda-consent-forms .tablenav.bottom {
31
+ display: none;
32
+ }
33
+ #iubenda-tabs .submit.submit-cons {
34
+ padding-top: 0;
35
+ }
36
+ #iubenda-tabs {
37
+ margin: 30px auto 20px;
38
+ }
39
+ #iub_parser_engine_container {
40
+ margin-top: 10px;
41
+ }
42
+ #iub_parser_engine_container > div:not(:last-child) {
43
+ margin-bottom: 10px;
44
+ }
45
+ #iub_amp_options_container {
46
+ margin-top: 10px;
47
+ }
48
+ #iub_amp_options_container > div:not(:last-child) {
49
+ margin-bottom: 10px;
50
+ }
51
+ #iubenda-tabs .contextual-help-wrap {
52
+ overflow: auto;
53
+ margin: 0;
54
+ position: relative;
55
+ }
56
+ #iubenda-tabs .contextual-help-back {
57
+ position: absolute;
58
+ top: 0;
59
+ bottom: 0;
60
+ left: 150px;
61
+ right: 0;
62
+ border: 1px solid #e1e1e1;
63
+ background: #f6fbfd;
64
+ }
65
+ #iubenda-tabs .contextual-help-columns {
66
+ position: relative;
67
+ }
68
+ #iubenda-tabs .help-tab-content {
69
+ margin-right: 0;
70
+ }
71
+ #iubenda-tabs .help-tab-content .description {
72
+ margin-bottom: 10px;
73
+ }
74
+ #iubenda-tabs .help-tab-content .custom-script-field, #iubenda-tabs .help-tab-content .custom-iframe-field {
75
+ padding-bottom: 10px;
76
+ }
77
+ #iubenda-tabs .help-tab-content .custom-script-field input, #iubenda-tabs .help-tab-content .custom-iframe-field input {
78
+ vertical-align: middle;
79
+ }
80
+ #tab-panel-scripts, #tab-panel-iframes {
81
+ margin-top: 16px;
82
+ margin-bottom: 18px;
83
+ }
84
+ #iubenda-tabs .postbox-container .widefat {
85
+ border: none;
86
+ box-shadow: none;
87
+ }
88
+ #iubenda-tabs .postbox-container .widefat h4 {
89
+ margin: 8px 0;
90
+ }
91
+ #iubenda-tabs .postbox-container .widefat select {
92
+ min-width: 50%;
93
+ }
94
+ #iubenda-tabs .postbox-container .widefat thead .label {
95
+ font-weight: bold;
96
+ }
97
+ #iubenda-tabs .postbox-container .widefat .table-label {
98
+ width: 25%;
99
+ }
100
+ #iubenda-tabs .postbox-container .widefat thead td {
101
+ border: none;
102
+ width: 50%;
103
+ }
104
+ #iubenda-tabs .postbox-container .widefat .widefat tbody td {
105
+ padding-top: 5px;
106
+ padding-bottom: 5px;
107
+ }
108
+ .iubenda-notice {
109
+ border-left-color: #1CC691;
110
+ padding-left: 0;
111
+ display: flex;
112
+ justify-content: flex-start;
113
+ align-items: center;
114
+ }
115
+ .iubenda-notice::before {
116
+ display: inline-block;
117
+ content: '';
118
+ height: 49px;
119
+ width: 22px;
120
+ margin: 1em 2em;
121
+ background-size: contain;
122
+ background-position: center center;
123
+ background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHdpZHRoPSIyMjFweCIgaGVpZ2h0PSI0OTBweCIgdmlld0JveD0iMCAwIDIyMSA0OTAiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+ICAgICAgICA8dGl0bGU+aXViZW5kYSB2ZWN0b3IgbG9nb192M19vbmx5X2lfZ3JlZW48L3RpdGxlPiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4gICAgPGRlZnM+PC9kZWZzPiAgICA8ZyBpZD0iUGFnZS0xIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj4gICAgICAgIDxnIGlkPSJpdWJlbmRhLXZlY3Rvci1sb2dvX3YzX29ubHlfaV9ncmVlbiIgZmlsbD0iIzFDQzY5MSIgZmlsbC1ydWxlPSJub256ZXJvIj4gICAgICAgICAgICA8cGF0aCBkPSJNMjIwLjYsMTA4LjQgQzIyMC42LDEzNSAyMTAuOCwxNTkuMyAxOTQuNSwxNzguMSBMMjE3LjksNDg5LjQgTDguNSw0ODkuNCBMMzEuMiwxODMuNSBDMTEuOSwxNjQuMiAwLDEzNy43IDAsMTA4LjQgQzAsNDguNyA0OS40LDAuNCAxMTAuMywwLjQgQzE3MS4yLDAuNCAyMjAuNiw0OC43IDIyMC42LDEwOC40IFogTTExMC4zLDEzMyBDMTI1LDEzMyAxMzYuOCwxMjEuMiAxMzYuOCwxMDYuNyBDMTM2LjgsOTIuMiAxMjQuOSw4MC41IDExMC4zLDgwLjUgQzk1LjYsODAuNSA4My44LDkyLjMgODMuOCwxMDYuNyBDODMuOCwxMjEuMyA5NS42LDEzMyAxMTAuMywxMzMgWiBNMTMxLjIsMjI3IEw5NC45LDI2My4zIEw5NC45LDQwMy44IEwxMzEuMiw0MDMuOCBMMTMxLjIsMjI3IFoiIGlkPSJTaGFwZSI+PC9wYXRoPiAgICAgICAgPC9nPiAgICA8L2c+PC9zdmc+);
124
+ }
125
+ .iubenda-notice .notice-question {
126
+ margin-bottom: 5px;
127
+ display: block;
128
+ }
129
+ .iubenda-notice .notice-reply {
130
+ margin-top: 0;
131
+ }
132
+ .iubenda-notice .step-2 {
133
+ display: none;
134
+ }
135
+ .iubenda-notice .reply-yes {
136
+ margin-right: 10px;
137
+ }
138
+ .iubenda-notice .reply-yes:before,
139
+ .iubenda-notice .reply-no:before {
140
+ font-family: dashicons;
141
+ display: inline-block;
142
+ line-height: 1;
143
+ font-weight: 400;
144
+ font-style: normal;
145
+ speak: none;
146
+ text-decoration: inherit;
147
+ text-transform: none;
148
+ text-rendering: auto;
149
+ -webkit-font-smoothing: antialiased;
150
+ -moz-osx-font-smoothing: grayscale;
151
+ width: 20px;
152
+ height: 20px;
153
+ font-size: 20px;
154
+ vertical-align: top;
155
+ text-align: center;
156
+ transition: color .1s ease-in;
157
+ text-decoration: none;
158
+ }
159
+ .iubenda-notice .reply-yes:before {
160
+ content: "\f147";
161
+ }
162
+ .iubenda-notice .reply-no:before {
163
+ content: "\f335";
164
+ }
trunk/includes/amp.php ADDED
@@ -0,0 +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
+ }
trunk/includes/forms-list-table.php ADDED
@@ -0,0 +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
+ }
trunk/includes/forms.php ADDED
@@ -0,0 +1,969 @@