PluginProbe ʕ •ᴥ•ʔ
Complianz – GDPR/CCPA Cookie Consent / 7.5.0
Complianz – GDPR/CCPA Cookie Consent v7.5.0
7.5.0 7.4.7 7.4.6 trunk 6.5.6 7.0.4 7.0.5 7.1.0 7.1.4 7.1.5 7.2.0 7.3.0 7.3.1 7.4.0 7.4.0.1 7.4.1 7.4.2 7.4.3 7.4.4 7.4.4.1 7.4.4.2 7.4.5 beta
complianz-gdpr / functions.php
complianz-gdpr Last commit date
DNSMPD 5 days ago assets 5 days ago config 3 months ago cookie 5 days ago cookiebanner 5 days ago cron 5 days ago documents 5 days ago gutenberg 2 months ago integrations 5 days ago languages 5 days ago mailer 1 year ago onboarding 1 year ago placeholders 7 months ago progress 2 years ago proof-of-consent 5 days ago rest-api 5 days ago settings 5 days ago templates 5 days ago upgrade 5 days ago websitescan 5 days ago LICENSE.txt 4 years ago README.md 7 months ago class-admin.php 5 days ago class-company.php 2 years ago class-cookie-blocker.php 5 days ago class-export.php 2 years ago class-installer.php 2 years ago class-review.php 5 days ago complianz-gpdr.php 5 days ago functions-legacy.php 2 years ago functions.php 5 days ago index.php 7 years ago loco.xml 4 years ago readme.txt 5 days ago security.md 2 years ago system-status.php 1 year ago uninstall.php 5 days ago upgrade.php 5 days ago wpml-config.xml 5 days ago
functions.php
3036 lines
1 <?php
2 defined( 'ABSPATH' ) or die( "you do not have access to this page!" );
3 require_once plugin_dir_path(__FILE__) . 'functions-legacy.php';
4
5 global $cmplz_banner;
6 if ( !function_exists('cmplz_get_cookiebanner')) {
7 function cmplz_get_cookiebanner($ID = false, $set_defaults = true, $load_wysiwyg_options = false){
8 global $cmplz_banner;
9
10 //try cached data if defaults are used
11 if ( $ID && $set_defaults && !$load_wysiwyg_options ) {
12 $banner = $cmplz_banner[ $ID ] ?? false;
13 if (!$banner){
14 $banner = new CMPLZ_COOKIEBANNER($ID, $set_defaults, $load_wysiwyg_options);
15 $cmplz_banner[ $ID ] = $banner;
16 }
17 } else {
18 $banner = new CMPLZ_COOKIEBANNER($ID, $set_defaults, $load_wysiwyg_options);
19 }
20 return $banner;
21 }
22 }
23 if ( ! function_exists( 'cmplz_get_option' ) ) {
24 /**
25 * Get a Complianz option by name
26 *
27 * @param string $name
28 * @param bool $default
29 *
30 * @return mixed
31 */
32 function cmplz_get_option( string $id, bool $load_default=true ) {
33 $id = cmplz_sanitize_title_preserve_uppercase($id);
34 //to ensure the fields function only runs once, we store it here, and check if it's filled in the next request.
35 $fields = false;
36 $options = get_option( 'cmplz_options', [] );
37 $value = $options[ $id ] ?? false;
38 if ( $value===false && $load_default && class_exists('COMPLIANZ') ) {
39 $fields = COMPLIANZ::$config->fields ?? [];
40 $keys = array_keys( array_column( $fields, 'id' ), $id );
41 $key = reset( $keys );
42 if (isset($fields[$key]) ) {
43 $default = $fields[ $key ]['default'] ?? false;
44 $value = apply_filters( 'cmplz_default_value', $default, $id, $fields[$key] );
45 }
46 }
47
48 /*
49 * Translate output
50 *
51 * */
52 if ( function_exists('pll__') || function_exists('icl_translate') || defined("WPML_PLUGIN_BASENAME" ) ) {
53 //check if Complianz::$config has property fields
54 if (class_exists('COMPLIANZ')) {
55 $config_fields = COMPLIANZ::$config->fields ?? [];
56 } else {
57 $config_fields = [];
58 }
59 $fields = $fields ?: $config_fields;
60 $keys = array_keys( array_column( $fields, 'id' ), $id );
61 $key = reset( $keys );
62 if ( $key !== false ) {
63 $type = $fields[ $key ]['type'] ?? false;
64 $translatable = $fields[ $key ]['translatable'] ?? false;
65 if ( $translatable ) {
66 if ( is_array( $value ) && ( $type === 'thirdparties' || $type === 'processors' ) ) {
67 foreach ( $value as $item_key => $item ) {
68 //contains the values of an item
69 foreach ( $item as $key => $key_value ) {
70 if ( function_exists( 'pll__' ) ) {
71 $value[ $item_key ][ $key ] = pll__( $item_key . '_' . $id . "_" . $key );
72 }
73 if ( function_exists( 'icl_translate' ) ) {
74 $value[ $item_key ][ $key ] = icl_translate( 'complianz', $item_key . '_' . $id . "_" . $key, $key_value );
75 }
76
77 $value[ $item_key ][ $key ] = apply_filters( 'wpml_translate_single_string', $key_value, 'complianz', $item_key . '_' . $id . "_" . $key );
78 }
79 }
80 } else {
81 if ( function_exists( 'pll__' ) ) {
82 $value = pll__( $value );
83 }
84 if ( function_exists( 'icl_translate' ) ) {
85 $value = icl_translate( 'complianz', $id, $value );
86 }
87 $value = apply_filters( 'wpml_translate_single_string', $value, 'complianz', $id );
88 }
89 }
90 }
91 }
92 return apply_filters("cmplz_option_$id", $value, $id);
93 }
94 }
95
96 if (!function_exists('cmplz_get_field')) {
97 function cmplz_get_field($id){
98 $fields = COMPLIANZ::$config->fields;
99 foreach ($fields as $field) {
100 if (isset($field['id']) && $field['id'] === $id) {
101 return $field;
102 }
103 }
104 return false;
105 }
106 }
107 if (!function_exists('cmplz_get_field_index')) {
108 function cmplz_get_field_index($id, $fields){
109 foreach ($fields as $index => $field) {
110 if (isset($field['id']) && $field['id'] === $id) {
111 return $index;
112 }
113 }
114 return false;
115 }
116 }
117
118 if ( !function_exists('cmplz_remove_field') ) {
119 /**
120 * @param array $fields
121 * @param $ids
122 *
123 * @return array
124 */
125 function cmplz_remove_field( array $fields, $ids): array {
126 if (!is_array($ids)) {
127 $ids = array($ids);
128 }
129 $field_ids = array_column($fields, 'id');
130 foreach ($ids as $id){
131 $drop_index = array_search( $id, $field_ids, true );
132 if ($drop_index!==false) {
133 unset($fields[$drop_index]);
134 }
135 }
136
137 return $fields;
138 }
139 }
140
141
142
143 if ( !function_exists('cmplz_sanitize_title_preserve_uppercase')) {
144 /**
145 * @param string $title
146 *
147 * @return string
148 */
149 function cmplz_sanitize_title_preserve_uppercase($title) {
150 if (empty($title)) {
151 return '';
152 }
153 $title = preg_replace( '/&.+?;/', '', $title );
154 $title = str_replace( '.', '-', $title );
155 $title = preg_replace( '/[^%a-zA-Z0-9 _-]/', '', $title );
156 $title = preg_replace( '/\s+/', '-', $title );
157 $title = preg_replace( '|-+|', '-', $title );
158 return str_replace(' ', '-', sanitize_text_field(remove_accents($title)));
159 }
160 }
161
162 if ( ! function_exists( 'cmplz_uses_google_analytics' ) ) {
163
164 /**
165 * Check if site uses google analytics
166 * @return bool
167 */
168
169 function cmplz_uses_google_analytics() {
170 return COMPLIANZ::$banner_loader->uses_google_analytics();
171 }
172 }
173
174 if ( ! function_exists( 'cmplz_consent_mode' ) ) {
175
176 /**
177 * Check if site uses google analytics
178 * @return bool
179 */
180
181 function cmplz_consent_mode() {
182 return cmplz_get_option( 'consent-mode' ) === 'yes';
183 }
184 }
185
186 if ( ! function_exists('cmplz_upload_dir')) {
187 /**
188 * Get the upload dir
189 *
190 * @param string $path
191 *
192 * @return string
193 */
194 function cmplz_upload_dir( string $path=''): string {
195 $uploads = wp_upload_dir();
196 $upload_dir = trailingslashit( apply_filters( 'cmplz_upload_dir', $uploads['basedir'] ) ).'complianz/'.$path;
197 if ( !is_dir( $upload_dir) ) {
198 cmplz_create_missing_directories_recursively($upload_dir);
199 }
200
201 return trailingslashit( $upload_dir );
202 }
203 }
204
205 /**
206 * Create directories recursively
207 *
208 * @param string $path
209 */
210
211 if ( !function_exists('cmplz_create_missing_directories_recursively') ) {
212 function cmplz_create_missing_directories_recursively( string $path ) {
213 if ( ! cmplz_user_can_manage() ) {
214 return;
215 }
216
217 $parts = explode( '/', $path );
218 $dir = '';
219 foreach ( $parts as $part ) {
220 $dir .= $part . '/';
221 if (cmplz_has_open_basedir_restriction($dir)) {
222 continue;
223 }
224 if ( ! is_dir( $dir ) && strlen( $dir ) > 0 && is_writable( dirname( $dir, 1 ) ) ) {
225 if ( ! mkdir( $dir ) && ! is_dir( $dir ) ) {
226 throw new \RuntimeException( sprintf( 'Directory "%s" was not created', $dir ) );
227 }
228 }
229 }
230 }
231 }
232
233
234 if (!function_exists('cmplz_has_open_basedir_restriction')) {
235 function cmplz_has_open_basedir_restriction($path) {
236 // Default error handler is required
237 set_error_handler(null);
238 // Clean last error info.
239 error_clear_last();
240 // Testing...
241 @file_exists($path);
242 // Restore previous error handler
243 restore_error_handler();
244 // Return `true` if error has occurred
245 return ($error = error_get_last()) && $error['message'] !== '__clean_error_info';
246 }
247 }
248
249 if ( ! function_exists('cmplz_upload_url')) {
250 /**
251 * Get the upload url
252 *
253 * @param string $path
254 *
255 * @return string
256 */
257 function cmplz_upload_url( string $path=''): string {
258 $uploads = wp_upload_dir();
259 $upload_url = $uploads['baseurl'];
260 $upload_url = trailingslashit( apply_filters('cmplz_upload_url', $upload_url) );
261 return trailingslashit($upload_url.'complianz/'.$path);
262 }
263 }
264
265 if ( ! function_exists( 'cmplz_uses_social_media' ) ) {
266
267 /**
268 * Check if site uses social media
269 * @return bool
270 */
271
272 function cmplz_uses_social_media() {
273 $socialmedia_list = cmplz_get_option( 'socialmedia_on_site' );
274 return is_array( $socialmedia_list ) && count( array_filter( $socialmedia_list ) ) > 0;
275 }
276 }
277
278 if ( !function_exists('cmplz_upgraded_to_current_version')){
279
280 /**
281 * Check if the user has upgraded to the current version, or if this is a fresh install with this version.
282 */
283
284 function cmplz_upgraded_to_current_version() {
285 $first_version = get_option( 'cmplz_first_version' );
286 //if there's no first version yet, we assume it's not upgraded
287 if ( !$first_version ) {
288 return false;
289 }
290 //if the first version is below current, we just upgraded.
291 if ( version_compare($first_version,CMPLZ_VERSION ,'<') ){
292 return true;
293 }
294 return false;
295 }
296 }
297
298 if ( ! function_exists( 'cmplz_is_new_install' ) ) {
299 /**
300 * Check whether this is a fresh installation at the current version.
301 *
302 * cmplz_first_version is written once in upgrade.php when no prior version
303 * exists, and is never updated afterwards. Comparing it to CMPLZ_VERSION
304 * distinguishes a fresh install (equal) from an upgrade (lower).
305 *
306 * Returns false when cmplz_first_version is absent — uncertain state,
307 * safe default to avoid showing upsells to existing users.
308 *
309 * @return bool True only when the plugin was installed fresh at the current version.
310 */
311 function cmplz_is_new_install(): bool {
312 $first_version = get_option( 'cmplz_first_version' );
313 if ( ! $first_version ) {
314 return false;
315 }
316 return version_compare( $first_version, CMPLZ_VERSION, '>=' );
317 }
318 }
319
320 if ( ! function_exists( 'cmplz_get_template' ) ) {
321 /**
322 * Get a template based on filename, overridable in theme dir
323 * @param string $filename
324 * @param array $args
325 * @param string $path
326 * @return string
327 */
328
329 function cmplz_get_template( $filename , $args = array(), $path = false ) {
330 $path = $path ? trailingslashit($path) : trailingslashit( CMPLZ_PATH ) . 'templates/';
331 $file = apply_filters('cmplz_template_file', $path . $filename, $filename);
332 $theme_file = trailingslashit( get_stylesheet_directory() )
333 . trailingslashit( basename( CMPLZ_PATH ) )
334 . 'templates/' . $filename;
335 if ( !file_exists( $file ) ) {
336 return false;
337 }
338
339 if ( file_exists( $theme_file ) ) {
340 $file = $theme_file;
341 }
342 if ( strpos( $file, '.php' ) !== false ) {
343 ob_start();
344 require $file;
345 $contents = ob_get_clean();
346 } else {
347 $contents = file_get_contents( $file );
348 }
349
350 if ( !empty($args) && is_array($args) ) {
351 foreach($args as $fieldname => $value ) {
352 $contents = str_replace( '{'.$fieldname.'}', $value, $contents );
353 }
354 }
355
356 return $contents;
357 }
358 }
359
360 if ( ! function_exists( 'cmplz_uses_google_tagmanager_or_analytics' ) ) {
361 function cmplz_uses_google_tagmanager_or_analytics(){
362 return COMPLIANZ::$banner_loader->uses_google_analytics() || COMPLIANZ::$banner_loader->uses_google_tagmanager();
363 }
364 }
365
366 if ( ! function_exists( 'cmplz_tagmanager_conditional_helptext' ) ) {
367
368 function cmplz_tagmanager_conditional_helptext() {
369
370 if ( !COMPLIANZ::$banner_loader->consent_required_for_anonymous_stats() ) {
371 $text = __( "Based on your Analytics configuration you should fire Analytics on event cmplz_functional.", 'complianz-gdpr' );
372 } else {
373 $text = __( "Based on your Analytics configuration you should fire Analytics on event cmplz_statistics.", 'complianz-gdpr' );
374 }
375
376 return $text;
377 }
378 }
379
380 if ( ! function_exists( 'cmplz_statistics_privacy_friendly' ) ) {
381
382 /**
383 * Checks if statistics are configured privacy friendly
384 *
385 * @return bool
386 */
387 function cmplz_statistics_privacy_friendly()
388 {
389 return COMPLIANZ::$banner_loader->statistics_privacy_friendly();
390 }
391 }
392
393 if ( ! function_exists( 'cmplz_manual_stats_config_possible' ) ) {
394
395 /**
396 * Checks if the statistics are configured so no consent is need for statistics
397 *
398 * @return bool
399 */
400
401 function cmplz_manual_stats_config_possible() {
402 $stats = cmplz_get_option( 'compile_statistics' );
403 if ( $stats === 'matomo' && cmplz_no_ip_addresses() ) {
404 return true;
405 }
406
407 //Google Tag Manager should also be possible to embed yourself if you haven't integrated it anonymously
408 if ( $stats === 'google-tag-manager' ) {
409 return true;
410 }
411
412 if ( $stats === 'google-analytics' ) {
413 if ( !COMPLIANZ::$banner_loader->consent_required_for_anonymous_stats()
414 ) {
415 return true;
416 }
417 }
418
419 return false;
420 }
421 }
422
423 if ( ! function_exists( 'cmplz_get_stats_tool_nice' ) ) {
424 function cmplz_get_stats_tool_nice() {
425 //if the user just changed the setting, we use the posted data. The data is not saved yet, so would yield the previous setting
426 if ( isset($_POST['cmplz_compile_statistics'])) {
427 $stats = sanitize_text_field($_POST['cmplz_compile_statistics']);
428 } else {
429 $stats = cmplz_get_option( 'compile_statistics' );
430 }
431 switch ( $stats ){
432 case 'google-analytics':
433 return "Google Analytics";
434 case 'matomo':
435 return "Matomo";
436 case 'clicky':
437 return "Clicky";
438 case 'yandex':
439 return "Yandex";
440 case 'google-tag-manager':
441 return "Google Tag Manager";
442 case 'matomo-tag-manager':
443 return "Matomo Tag Manager";
444 case 'clarity':
445 return "Clarity";
446 default:
447 return __("Not found","complianz-gdpr");
448 }
449 }
450 }
451
452 if ( !function_exists('cmplz_detected_cookie_plugin')) {
453 function cmplz_detected_cookie_plugin( $return_name = false ){
454 $plugin = false;
455 if (defined('CLI_LATEST_VERSION_NUMBER')){
456 $plugin = "GDPR Cookie Consent";
457 } elseif(defined('MOOVE_GDPR_VERSION')) {
458 $plugin = "GDPR Cookie Compliance";
459 }elseif(defined('CTCC_PLUGIN_URL')) {
460 $plugin = "GDPR Cookie Consent Banner";
461 }elseif(defined('RCB_FILE')) {
462 $plugin = "Real Cookie Banner";
463 }elseif(class_exists('Cookiebot_WP')) {
464 $plugin = "Cookiebot";
465 }elseif(function_exists('bst_plugin_install')) {
466 $plugin = "BST DSGVO Cookie";
467 }elseif(function_exists('jlplg_lovecoding_set_cookie')) {
468 $plugin = "Simple Cookie Notice";
469 }elseif(class_exists('SCCBPP_WpCookie_Save')) {
470 $plugin = "Seers Cookie Consent Banner Privacy Policy";
471 }elseif(function_exists('daextlwcnf_customize_action_links')) {
472 $plugin = "Lightweight Cookie Notice Free";
473 }elseif(defined('GDPRCN_VERSION')) {
474 $plugin = "GDPR Cookie Notice";
475 }elseif(function_exists('wp_gdpr_cookie_notice_check_requirements')) {
476 $plugin = "WP GDPR Cookie Notice";
477 }elseif(defined('SURBMA_GPGA_PLUGIN_VERSION_NUMBER')) {
478 $plugin = "Surbma | GDPR Proof Cookie Consent & Notice Bar";
479 }elseif(class_exists('dsdvo_wp_backend')) {
480 $plugin = "DSGVO All in one for WP";
481 }elseif(class_exists('Cookie_Notice')) {
482 $plugin = "Cookie Notice & Compliance";
483 }elseif(defined('CNCB_VERSION')) {
484 $plugin = "Cookie Notice and Consent Banner";
485 }elseif(function_exists('add_cookie_notice')) {
486 $plugin = "Cookie Notice Lite";
487 }elseif(function_exists('fhw_dsgvo_cookie_insert')) {
488 $plugin = "GDPR tools: cookie notice + privacy";
489 }elseif(defined('GDPR_COOKIE_CONSENT_PLUGIN_URL')) {
490 $plugin = "GDPR Cookie Consent";
491 }elseif(defined('WP_GDPR_C_SLUG')) {
492 $plugin = "WP GDPR Compliance";
493 }elseif(defined('TERMLY_VERSION')) {
494 $plugin = "Termly | GDPR/CCPA Cookie Consent Banner";
495 }
496
497 if ( $plugin !== false && !$return_name ) {
498 return true;
499 } else {
500 return $plugin;
501 }
502 }
503 }
504
505 if ( ! function_exists( 'cmplz_revoke_link' ) ) {
506 /**
507 * Output a revoke button
508 * @param bool $text
509 *
510 * @return string
511 */
512 function cmplz_revoke_link( $text = false ) {
513 $text = sanitize_text_field($text) ? : __( 'Revoke', 'complianz-gdpr' );
514 $text = apply_filters( 'cmplz_revoke_button_text', $text );
515 $css
516 = "<style>.cmplz-status-accepted,.cmplz-status-denied {display: none;}</style>
517 <script>
518 document.addEventListener('cmplz_before_cookiebanner', function(){
519 if (cmplz_has_consent('marketing')) {
520 document.querySelector('.cmplz-status-accepted').style.display = 'block';
521 document.querySelector('.cmplz-status-denied').style.display = 'none';
522 } else {
523 document.querySelector('.cmplz-status-accepted').style.display = 'none';
524 document.querySelector('.cmplz-status-denied').style.display = 'block';
525 document.querySelector('.cmplz-revoke-custom').setAttribute('disabled', true);
526
527 }
528 document.addEventListener('click', e => {
529 if ( e.target.closest('.cmplz-revoke-custom') ) {
530 document.querySelector('.cmplz-revoke-custom').setAttribute('disabled', true);
531 cmplz_set_banner_status('dismissed');
532 }
533 });
534 document.addEventListener('click', e => {
535 if ( e.target.closest('.cmplz-accept') ) {
536 document.querySelector('.cmplz-status-accepted').style.display = 'block';
537 document.querySelector('.cmplz-status-denied').style.display = 'none';
538 document.querySelector('.cmplz-revoke-custom').removeAttribute('disabled');
539 }
540 });
541 });
542 </script>";
543 $html = $css . '<button class="cmplz-deny cmplz-revoke-custom">' . esc_html($text)
544 . '</button>&nbsp;<span class="cmplz-status-accepted">'
545 . cmplz_sprintf( __( 'Current status: %s', 'complianz-gdpr' ),
546 __( "Accepted", 'complianz-gdpr' ) )
547 . '</span><span class="cmplz-status-denied">'
548 . cmplz_sprintf( __( 'Current status: %s', 'complianz-gdpr' ),
549 __( "Denied", 'complianz-gdpr' ) ) . '</span>';
550
551 return apply_filters( 'cmplz_revoke_link', $html );
552 }
553 }
554
555 if ( ! function_exists( 'cmplz_sells_personal_data' ) ) {
556 function cmplz_sells_personal_data() {
557 $purposes = cmplz_get_option( 'purpose_personaldata');
558 if ( isset( $purposes['selling-data-thirdparty'] )
559 && $purposes['selling-data-thirdparty']
560 ) {
561 return true;
562 }
563
564 return false;
565 }
566 }
567 if ( ! function_exists( 'cmplz_sold_data_12months' ) ) {
568 function cmplz_sold_data_12months() {
569 return COMPLIANZ::$company->sold_data_12months();
570 }
571 }
572 if ( ! function_exists( 'cmplz_disclosed_data_12months' ) ) {
573 function cmplz_disclosed_data_12months() {
574 return COMPLIANZ::$company->disclosed_data_12months();
575 }
576 }
577
578 if ( ! function_exists( 'cmplz_site_needs_cookie_warning' ) ) {
579 /**
580 * Check if site needs a cookie warning
581 *
582 * @return bool
583 */
584 function cmplz_site_needs_cookie_warning() {
585 return COMPLIANZ::$banner_loader->site_needs_cookie_warning();
586 }
587 }
588 if ( ! function_exists( 'cmplz_eu_site_needs_cookie_warning' ) ) {
589 /**
590 * Check if EU targeted site needs a cookie warning
591 *
592 * @return bool
593 */
594 function cmplz_eu_site_needs_cookie_warning() {
595 return COMPLIANZ::$banner_loader->site_needs_cookie_warning( 'eu' );
596 }
597 }
598
599 if ( ! function_exists( 'cmplz_za_site_needs_cookie_warning' ) ) {
600 /**
601 * Check if ZA targeted site needs a cookie warning
602 *
603 * @return bool
604 */
605 function cmplz_za_site_needs_cookie_warning() {
606 return COMPLIANZ::$banner_loader->site_needs_cookie_warning( 'za' );
607 }
608 }
609
610 if ( ! function_exists( 'cmplz_uk_site_needs_cookie_warning' ) ) {
611 /**
612 * Check if EU targeted site needs a cookie warning
613 *
614 * @return bool
615 */
616 function cmplz_uk_site_needs_cookie_warning() {
617 return COMPLIANZ::$banner_loader->site_needs_cookie_warning( 'uk' );
618 }
619 }
620
621 if ( ! function_exists( 'cmplz_site_uses_cookie_warning_cats' ) ) {
622
623 /**
624 * Check if optin site needs cookie warning with categories
625 * @return bool
626 */
627 function cmplz_site_uses_cookie_warning_cats() {
628 $cookiebanner = cmplz_get_cookiebanner( apply_filters( 'cmplz_user_banner_id', cmplz_get_default_banner_id() ) );
629 if ( $cookiebanner->use_categories !== 'no'
630 ) {
631 return true;
632 }
633
634 return false;
635 }
636 }
637
638 if ( ! function_exists( 'cmplz_company_located_in_region' ) ) {
639
640 /**
641 * Check if this company is located in a certain region
642 *
643 * @param $region
644 *
645 * @return bool
646 */
647 function cmplz_company_located_in_region( $region ) {
648 $country_code = cmplz_get_option( 'country_company' );
649
650 return ( cmplz_get_region_for_country( $country_code ) === $region );
651 }
652 }
653
654 if ( ! function_exists( 'cmplz_has_region' ) ) {
655 /**
656 * Check if this website targets a specific region.
657 *
658 * @param string $code
659 *
660 * @return bool
661 */
662 function cmplz_has_region( $code ) {
663 $regions = cmplz_get_regions(true);
664 if ( in_array( $code, $regions ) ) {
665 return true;
666 }
667
668 return false;
669 }
670 }
671
672 if ( ! function_exists( 'cmplz_has_state' ) ) {
673 /**
674 * Check if this website targets a specific state
675 *
676 * @param string $code
677 *
678 * @return bool
679 */
680 function cmplz_has_state( $code ) {
681 $regions = cmplz_get_regions(true);
682 if ( !isset( $regions[ 'us' ] ) ) {
683 return false;
684 }
685
686 $states = cmplz_get_option('us_states');
687 if ( isset( $states[ $code ] ) ) {
688 return true;
689 }
690 return false;
691 }
692 }
693
694 if ( ! function_exists( 'cmplz_get_region_from_legacy_type' ) ) {
695 function cmplz_get_region_from_legacy_type( $type ) {
696 $region = false;
697 if ( strpos( $type, 'disclaimer' ) !== false || strpos( $type, 'all' ) !== false ) {
698 $region = 'all';
699 }
700 //get last three chars of string. if not contains -, it's eu or disclaimer.
701 if ( substr( $type, - 3, 1 ) === '-' ) {
702 $region = substr( $type, - 2 );
703 }
704 if ( ! $region ) {
705 $region = 'eu';
706 }
707
708 return $region;
709 }
710 }
711
712 if (!function_exists('cmplz_format_as_javascript_array')) {
713 function cmplz_format_as_javascript_array($array) {
714 $out = [];
715 foreach ($array as $key => $label){
716 $out[] = [
717 'id' => $key,
718 'label' => $label,
719 ];
720 }
721 return $out;
722 }
723 }
724
725 if ( ! function_exists( 'cmplz_get_regions' ) ) {
726 function cmplz_get_regions( $ad_all_category = false, $label_type = false ) {
727 $regions = cmplz_get_option( 'regions' );
728 if ( ! is_array( $regions ) ) {
729 $regions = !empty( $regions ) ? array( $regions ) : [];
730 }
731
732 if ( $label_type && ! empty( $regions ) ) {
733 $output = array();
734 foreach ( $regions as $region ) {
735 if ($label_type==='full') {
736 $label = isset( COMPLIANZ::$config->regions[ $region ] ) ? COMPLIANZ::$config->regions[ $region ]['label_full'] : '';
737 } else {
738 $label = isset( COMPLIANZ::$config->regions[ $region ] ) ? COMPLIANZ::$config->regions[ $region ]['label'] : '';
739 }
740 $output[ $region ] = $label;
741 }
742 } else {
743 $output = $regions;
744 }
745
746 if ( $ad_all_category ) {
747 if ($label_type) {
748 $output['all'] = __( 'General', 'complianz-gdpr' );
749 } else {
750 $output[] = 'all';
751 }
752 }
753 return array_filter($output);
754 }
755 }
756
757 if ( ! function_exists( 'cmplz_multiple_regions' ) ) {
758
759 function cmplz_multiple_regions() {
760 //if geo ip is not enabled, return false anyway
761 if ( ! cmplz_geoip_enabled() ) {
762 return false;
763 }
764
765 $regions = cmplz_get_regions();
766
767 return count( $regions ) > 1;
768 }
769 }
770
771 if ( ! function_exists( 'cmplz_get_region_for_country' ) ) {
772
773 function cmplz_get_region_for_country( $country_code ) {
774 $region = false;
775 $regions = COMPLIANZ::$config->regions;
776 foreach ( $regions as $region_code => $region_data ) {
777 if ( in_array( $country_code, $region_data['countries'] ) ) {
778 $region = $region_code;
779 break;
780 }
781 }
782 return apply_filters( "cmplz_region_for_country", $region, $country_code );
783 }
784 }
785
786 if ( ! function_exists( 'cmplz_get_consenttype_for_country' ) ) {
787 function cmplz_get_consenttype_for_country( $country_code ) {
788 $regions = COMPLIANZ::$config->regions;
789 $used_regions = cmplz_get_regions();
790 //do not unset a not used region if it's a manual override.
791 if ( !isset($_GET['cmplz_user_region']) ) {
792 foreach ( $regions as $region => $region_data ) {
793 if ( empty($used_regions) || !in_array( $region, $used_regions )) {
794 unset($regions[$region]);
795 }
796 }
797 }
798
799 $actual_region = apply_filters('cmplz_user_region', cmplz_get_region_for_country( $country_code ));
800 if ( isset( $regions[ $actual_region ]) && isset( $regions[ $actual_region ]['type'] ) ) {
801 $consenttype = apply_filters( 'cmplz_consenttype', $regions[ $actual_region ]['type'], $actual_region );
802 return $consenttype;
803 }
804 return false;
805 }
806 }
807
808 if ( ! function_exists( 'cmplz_targeting_multiple_regions' ) ) {
809 function cmplz_targeting_multiple_regions(){
810 if ( defined("POLYLANG_VERSION" ) ) return true;
811 if ( defined("WPML_PLUGIN_BASENAME" ) ) return true;
812
813 return false;
814 }
815 }
816
817 /**
818 * Check if the scan detected social media on the site.
819 *
820 *
821 * */
822 if ( ! function_exists( 'cmplz_scan_detected_social_media' ) ) {
823
824 function cmplz_scan_detected_social_media() {
825 $social_media = get_option( 'cmplz_detected_social_media', array() );
826 if ( ! is_array( $social_media ) ) {
827 $social_media = array( $social_media );
828 }
829 $social_media = array_filter( $social_media );
830
831 $social_media = apply_filters( 'cmplz_detected_social_media',
832 $social_media );
833
834 //nothing scanned yet, or nothing found
835 if ( ! $social_media || ( count( $social_media ) == 0 ) ) {
836 $social_media = false;
837 }
838
839 return $social_media;
840 }
841 }
842
843 if ( ! function_exists( 'cmplz_scan_detected_thirdparty_services' ) ) {
844
845 function cmplz_scan_detected_thirdparty_services() {
846 $thirdparty = get_option( 'cmplz_detected_thirdparty_services', array() );
847 if ( ! is_array( $thirdparty ) ) {
848 $thirdparty = array( $thirdparty );
849 }
850 $thirdparty = array_filter( $thirdparty );
851 $thirdparty = apply_filters( 'cmplz_detected_services', $thirdparty );
852
853 //nothing scanned yet, or nothing found
854 if ( ! $thirdparty || ( count( $thirdparty ) == 0 ) ) {
855 $thirdparty = false;
856 }
857
858 return $thirdparty;
859 }
860 }
861
862
863 if ( ! function_exists( 'cmplz_scan_detected_stats' ) ) {
864
865 function cmplz_scan_detected_stats() {
866 $stats = get_option( 'cmplz_detected_stats', array() );
867 if ( ! is_array( $stats ) ) {
868 $stats = array( $stats );
869 }
870 $stats = array_filter( $stats );
871 //nothing scanned yet, or nothing found
872 if ( ! $stats || ( count( $stats ) == 0 ) ) {
873 $stats = false;
874 }
875
876 $stats = apply_filters( 'cmplz_detected_stats', $stats );
877
878 return $stats;
879 }
880 }
881
882 if ( ! function_exists( 'cmplz_page_is_of_type' ) ) {
883 /**
884 * Save a complianz option
885 * @param string $type
886 * @return bool
887 */
888 function cmplz_page_is_of_type( $type ) {
889 $regions = cmplz_get_regions();
890 global $post;
891 if ( !$post ) return false;
892
893 $post_id = $post->ID;
894 foreach ( $regions as $region ) {
895 $policy_id = COMPLIANZ::$document->get_shortcode_page_id( $type, $region );
896 if ( $policy_id === $post_id ) {
897 return true;
898 }
899 }
900 return false;
901 }
902 }
903
904 if ( ! function_exists( 'cmplz_uses_statistics' ) ) {
905 function cmplz_uses_statistics() {
906 $stats = cmplz_get_option( 'compile_statistics' );
907 if ( $stats !== 'no' ) {
908 return true;
909 }
910
911 return false;
912 }
913 }
914
915 if ( ! function_exists( 'cmplz_show_install_burst_warning' ) ) {
916 function cmplz_show_install_burst_warning() {
917 if ( cmplz_get_option('consent_for_anonymous_stats') === 'yes' && !defined( 'burst_version' ) ) {
918 return true;
919 }
920 return false;
921 }
922 }
923
924
925 if ( ! function_exists( 'cmplz_uses_only_functional_cookies' ) ) {
926 function cmplz_uses_only_functional_cookies() {
927 return COMPLIANZ::$banner_loader->uses_only_functional_cookies();
928 }
929 }
930
931 if ( !function_exists('cmplz_scan_in_progress')) {
932 function cmplz_scan_in_progress(){
933 return isset( $_GET['complianz_scan_token'] ) && wp_verify_nonce( $_GET['complianz_scan_token'], 'complianz_scan_token');
934 }
935 }
936
937 if ( ! function_exists( 'cmplz_ecommerce_legal' ) ) {
938 function cmplz_ecommerce_legal() {
939
940 //check Woo and EDD constants
941 $ecommerce_enabled = defined('WC_PLUGIN_FILE') || defined('EDD_VERSION');
942
943 return $ecommerce_enabled;
944 }
945 }
946
947 if ( ! function_exists( 'cmplz_site_shares_data' ) ) {
948 /**
949 * Function to check if site shares data. Used in canada cookie policy
950 * @return bool
951 */
952 function cmplz_site_shares_data() {
953 return COMPLIANZ::$banner_loader->site_shares_data();
954 }
955 }
956
957 if ( ! function_exists( 'cmplz_strip_spaces' ) ) {
958
959 function cmplz_strip_spaces( $string ) {
960 return preg_replace( '/\s*/m', '', $string );
961
962 }
963 }
964
965 if ( ! function_exists( 'cmplz_localize_date' ) ) {
966
967 function cmplz_localize_date( $unix_time ) {
968 $formatted_date = date( get_option( 'date_format' ), $unix_time );
969 $month = date( 'F', $unix_time ); //june
970 $month_localized = __( $month ); //juni
971 $date = str_replace( $month, $month_localized, $formatted_date );
972 $weekday = date( 'l', $unix_time ); //wednesday
973 $weekday_localized = __( $weekday ); //woensdag
974 $date = str_replace( $weekday, $weekday_localized, $date );
975 return $date;
976 }
977 }
978
979 if (!function_exists('cmplz_strpos_arr')) {
980 /**
981 * check if there is a partial match between a key of the array and the haystack
982 * We cannot use array_search, as this would not allow partial matches.
983 *
984 * @param string $haystack
985 * @param array $needle
986 *
987 * @return bool|string
988 */
989
990 function cmplz_strpos_arr( $haystack, $needle ) {
991 if ( empty( $haystack ) ) {
992 return false;
993 }
994 if ( ! is_array( $needle ) ) {
995 $needle = array( $needle );
996 }
997 foreach ( $needle as $key => $value ) {
998 if ( strlen($value) === 0 ) continue;
999 if ( ( strpos( $haystack, $value ) ) !== false ) {
1000 return ( is_numeric( $key ) ) ? $value : $key;
1001 }
1002 }
1003
1004 return false;
1005 }
1006 }
1007
1008 /**
1009 * callback for privacy document Check if there is a text entered in the custom privacy statement text
1010 *
1011 * */
1012 if ( ! function_exists( 'cmplz_has_custom_privacy_policy' ) ) {
1013 function cmplz_has_custom_privacy_policy() {
1014 $policy = cmplz_get_option( 'custom_privacy_policy_text' );
1015 if ( empty( $policy ) ) {
1016 return false;
1017 }
1018
1019 return true;
1020 }
1021 }
1022
1023 /**
1024 * callback for privacy statement document, check if google is allowed to share data with other services
1025 *
1026 * */
1027 if ( ! function_exists( 'cmplz_statistics_no_sharing_allowed' ) ) {
1028 function cmplz_statistics_no_sharing_allowed() {
1029
1030 $statistics = cmplz_get_option( 'compile_statistics', false,
1031 'wizard' );
1032 $tagmanager = ( $statistics === 'google-tag-manager' ) ? true
1033 : false;
1034 $google_analytics = ( $statistics === 'google-analytics' ) ? true
1035 : false;
1036
1037 if ( $google_analytics || $tagmanager ) {
1038 $thirdparty = $google_analytics
1039 ? cmplz_get_option( 'compile_statistics_more_info' )
1040 : cmplz_get_option( 'compile_statistics_more_info_tag_manager');
1041 if ( !is_array($thirdparty) ) {
1042 $thirdparty = array();
1043 }
1044 return in_array( 'no-sharing', $thirdparty, true );
1045 }
1046
1047 //only applies to google
1048 return false;
1049 }
1050 }
1051
1052 /**
1053 * callback for privacy statement document. Check if ip addresses are stored.
1054 *
1055 * */
1056 if ( ! function_exists( 'cmplz_no_ip_addresses' ) ) {
1057 function cmplz_no_ip_addresses() {
1058 $statistics = cmplz_get_option( 'compile_statistics');
1059
1060 //not anonymous stats.
1061 if ( $statistics === 'yes' ) {
1062 return false;
1063 }
1064
1065 $tagmanager = ( $statistics === 'google-tag-manager' ) ? true : false;
1066 $matomo = ( $statistics === 'matomo' ) ? true : false;
1067 $google_analytics = ( $statistics === 'google-analytics' ) ? true : false;
1068
1069 if ( $google_analytics || $tagmanager ) {
1070 $thirdparty = $google_analytics
1071 ? cmplz_get_option( 'compile_statistics_more_info')
1072 : cmplz_get_option( 'compile_statistics_more_info_tag_manager');
1073 if ( !is_array($thirdparty) ) {
1074 $thirdparty = array();
1075 }
1076 return in_array( 'ip-addresses-blocked', $thirdparty, true );
1077 }
1078
1079 if ( $matomo ) {
1080 return false;
1081 }
1082
1083 return false;
1084 }
1085 }
1086
1087 if (!function_exists('cmplz_get_console_errors')){
1088 /**
1089 * Get console errors as detected by complianz
1090 * @return string
1091 */
1092 function cmplz_get_console_errors(){
1093 $errors = get_option('cmplz_detected_console_errors');
1094 $location = isset($errors[2]) && strlen($errors[2])>0 ? $errors[2] : __('the page source', 'complianz-gdpr');
1095 $line_no = isset($errors[1]) ? $errors[1] : 0;
1096 if ( $errors && isset($errors[0]) && $line_no>1 ) {
1097 return cmplz_sprintf(__('%s on line %s of %s', 'complianz-gdpr'), $errors[0], $errors[1], $location);
1098 }
1099
1100 return false;
1101 }
1102 }
1103
1104 if ( ! function_exists( 'cmplz_cookie_warning_required_stats_eu' ) ) {
1105 function cmplz_cookie_warning_required_stats_eu() {
1106 return COMPLIANZ::$banner_loader->cookie_warning_required_stats('eu');
1107 }
1108 }
1109
1110 if ( ! function_exists( 'cmplz_cookie_warning_required_stats_uk' ) ) {
1111 function cmplz_cookie_warning_required_stats_uk() {
1112 return COMPLIANZ::$banner_loader->cookie_warning_required_stats('uk');
1113 }
1114 }
1115
1116 if ( ! function_exists( 'cmplz_cookie_warning_required_stats_za' ) ) {
1117 function cmplz_cookie_warning_required_stats_za() {
1118 return COMPLIANZ::$banner_loader->cookie_warning_required_stats('za');
1119 }
1120 }
1121
1122
1123
1124
1125 if ( ! function_exists( 'cmplz_accepted_processing_agreement' ) ) {
1126 function cmplz_accepted_processing_agreement() {
1127 $statistics = cmplz_get_option( 'compile_statistics' );
1128 $tagmanager = $statistics === 'google-tag-manager';
1129 $google_analytics = $statistics === 'google-analytics';
1130
1131 if ( $google_analytics || $tagmanager ) {
1132 $thirdparty = $google_analytics
1133 ? cmplz_get_option( 'compile_statistics_more_info' )
1134 : cmplz_get_option( 'compile_statistics_more_info_tag_manager' );
1135 if ( !is_array($thirdparty) ) {
1136 $thirdparty = array();
1137 }
1138
1139 return in_array( 'accepted', $thirdparty, true );
1140 }
1141
1142 //only applies to google
1143 return false;
1144 }
1145 }
1146
1147 if ( ! function_exists( 'cmplz_init_cookie_blocker' ) ) {
1148
1149 /**
1150 * Check if the Cookie Blocker should run
1151 * @param bool $admin_test
1152 * @return bool
1153 */
1154
1155 function cmplz_can_run_cookie_blocker( $admin_test = false ){
1156 if ( ! COMPLIANZ::$banner_loader->site_needs_cookie_warning() ) {
1157 return false;
1158 }
1159
1160 if ( cmplz_get_option('enable_cookie_blocker') !== 'yes' ) {
1161 return false;
1162 }
1163
1164 //we can pass a variable $admin_test=true if we want to test cookieblocker availability from admin
1165 if ( !$admin_test ) {
1166 //only allow cookieblocker on admin when it's an ajax request
1167 if ( ! wp_doing_ajax() && is_admin() ) {
1168 return false;
1169 }
1170 }
1171
1172 if ( is_feed() ) {
1173 return false;
1174 }
1175
1176 //don't fire on the back-end
1177 if ( is_preview() || cmplz_is_pagebuilder_preview() || isset($_GET["cmplz_safe_mode"]) ) {
1178 return false;
1179 }
1180
1181 if ( defined( 'CMPLZ_DO_NOT_BLOCK' ) && CMPLZ_DO_NOT_BLOCK ) {
1182 return false;
1183 }
1184
1185 if ( cmplz_get_option( 'safe_mode' ) ) {
1186 return false;
1187 }
1188
1189 /* Do not block when visitors are from outside EU or US, if geoip is enabled */
1190 //check cache, as otherwise all users would get the same output, while this is user specific
1191 //@todo better check for any caching plugin, as this check does not work with wp rocket for example.
1192 //if (!defined('wp_cache') && class_exists('cmplz_geoip') && COMPLIANZ::$geoip->geoip_enabled() && (COMPLIANZ::$geoip->region() !== 'eu') && (COMPLIANZ::$geoip->region() !== 'us')) return;
1193
1194 //do not block cookies during the scan
1195 if ( cmplz_scan_in_progress() ) {
1196 return false;
1197 }
1198
1199 /* Do not fix block when call is coming from wp_api or from xmlrpc or feed */
1200 if ( defined( 'JSON_REQUEST' ) && JSON_REQUEST ) {
1201 return false;
1202 }
1203 if ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST ) {
1204 return false;
1205 }
1206 return true;
1207 }
1208 }
1209
1210 if ( ! function_exists( 'cmplz_init_cookie_blocker' ) ) {
1211 function cmplz_init_cookie_blocker() {
1212
1213 if ( !cmplz_can_run_cookie_blocker() ) {
1214 return;
1215 }
1216
1217 if ( wp_doing_ajax() ) {
1218 add_action( "admin_init", array( COMPLIANZ::$cookie_blocker, "start_buffer" ) );
1219 } else {
1220 if (cmplz_is_amp()) {
1221 add_action( "wp", array( COMPLIANZ::$cookie_blocker, "start_buffer" ) , 20);
1222 } else {
1223 add_action( "template_redirect", array( COMPLIANZ::$cookie_blocker, "start_buffer" ) );
1224 }
1225 }
1226 add_action( "shutdown",
1227 array( COMPLIANZ::$cookie_blocker, "end_buffer" ), 999 );
1228
1229 }
1230 }
1231
1232 /**
1233 * check if a pdf document is being generated
1234 *
1235 * @return bool
1236 */
1237
1238 if ( !function_exists('cmplz_is_loading_pdf')) {
1239 function cmplz_is_loading_pdf() {
1240 return cmplz_user_can_manage() && isset( $_GET['nonce'] ) && wp_verify_nonce( $_GET['nonce'], 'cmplz_pdf_nonce' );
1241 }
1242 }
1243
1244 /**
1245 *
1246 * Check if we are currently in preview mode from one of the known page builders
1247 *
1248 * @return bool
1249 * @since 2.0.7
1250 *
1251 */
1252 if ( ! function_exists( 'cmplz_is_pagebuilder_preview' ) ) {
1253 function cmplz_is_pagebuilder_preview() {
1254 $preview = false;
1255 global $wp_customize;
1256 if ( isset( $wp_customize )
1257 || isset( $_GET['fb-edit'] ) //avada
1258 || isset( $_GET['builder_id'] ) //avada
1259 || isset( $_GET['et_pb_preview'] ) //divi
1260 || isset( $_GET['et_fb'] ) //divi
1261 || isset( $_GET['elementor-preview'] )
1262 || isset( $_GET['elementor_library'] )
1263 || isset( $_GET['elementor-app'] )
1264 || isset( $_GET['vc_action'] )
1265 || isset( $_GET['vc_editable'] )
1266 || isset( $_GET['vcv-action'] )
1267 || isset( $_GET['zion_builder_active'])
1268 || isset( $_GET['zionbuilder-preview'])
1269 || isset( $_GET['tb-preview']) //themify
1270 || isset( $_GET['tb-id']) //themify
1271 || isset( $_GET['fl_builder'] )
1272 || isset( $_GET['tve'] )
1273 || isset( $_GET['bricks'] ) //bricks builder
1274 || isset( $_GET['ct_builder'] ) //oxygen
1275 || isset( $_GET['tatsu'] ) //tatsu
1276 || isset( $_GET['tatsu-header'] ) //tatsu
1277 || isset( $_GET['tatsu-footer'] ) //tatsu
1278 || ( isset( $_GET['action'] ) && $_GET['action'] === 'ms_get_preview' ) //meta slider
1279 || strpos( $_SERVER['REQUEST_URI'], 'cornerstone/edit') !== false
1280 ) {
1281 $preview = true;
1282 }
1283
1284 //exclude widgets, and don't exclude banner api
1285 $request_url = isset($_SERVER['REQUEST_URI']) ? esc_url_raw($_SERVER['REQUEST_URI']) : '';
1286 if ( strpos($request_url, 'wp-json/complianz/')===false && defined( 'REST_REQUEST' ) && REST_REQUEST ) {
1287 return true;
1288 }
1289
1290 if (isset($_GET['context']) && $_GET['context']==='edit') {
1291 return true;
1292 }
1293 return apply_filters( 'cmplz_is_preview', $preview );
1294 }
1295 }
1296
1297 if (!function_exists('cmplz_datarequests_active')) {
1298 /**
1299 * Check if the site requires DNSMPI logic
1300 *
1301 * @return bool
1302 */
1303 function cmplz_datarequests_active() {
1304 return cmplz_get_option( 'datarequest' ) === 'yes';
1305 }
1306 }
1307
1308 if (!function_exists('cmplz_datarequests_or_dnsmpi_active')) {
1309 /**
1310 * Check if the site requires data requests OR dnsmpi logic
1311 *
1312 * @return bool
1313 */
1314 function cmplz_datarequests_or_dnsmpi_active() {
1315 return cmplz_datarequests_active() || cmplz_has_region('us');
1316 }
1317 }
1318
1319 if (!function_exists('cmplz_file_exists_on_url')) {
1320 function cmplz_file_exists_on_url($url){
1321 $upload_dir = cmplz_upload_dir();
1322 $upload_url = cmplz_upload_url();
1323 $path = str_replace( $upload_url, $upload_dir, $url );
1324 return file_exists($path);
1325 }
1326 }
1327
1328 if ( ! function_exists( 'cmplz_geoip_enabled' ) ) {
1329 function cmplz_geoip_enabled() {
1330 return apply_filters( 'cmplz_geoip_enabled', false );
1331 }
1332 }
1333
1334 if ( ! function_exists( 'cmplz_tcf_active' ) ) {
1335 function cmplz_tcf_active() {
1336 if ( !defined('cmplz_premium') ) {
1337 return false;
1338 }
1339
1340 if ( cmplz_get_option('uses_ad_cookies') !=='yes' ) {
1341 return false;
1342 }
1343
1344 $tcf_active = cmplz_get_option('uses_ad_cookies_personalized') === 'tcf' || cmplz_get_option('uses_ad_cookies_personalized') === 'yes';
1345 return apply_filters( 'cmplz_is_tcf_active', $tcf_active );
1346 }
1347 }
1348
1349
1350 if ( !function_exists('cmplz_get_transient') ) {
1351
1352 /**
1353 * We user our own transient, as the wp transient is not always persistent
1354 *
1355 * @param string $name
1356 *
1357 * @return mixed
1358 */
1359 function cmplz_get_transient( string $name ){
1360 if ( isset($_GET['cmplz_nocache']) ) {
1361 return false;
1362 }
1363
1364 $value = false;
1365 $now = time();
1366 $transients = get_option( 'cmplz_transients', array() );
1367
1368 if ( isset( $transients[ $name ] ) ) {
1369 $data = $transients[ $name ];
1370 $expires = isset( $data[ 'expires' ]) ? $data[ 'expires' ] : 0;
1371 $value = isset( $data['value'] ) ? $data[ 'value' ] : false;
1372 if ( $expires < $now ) {
1373 unset( $transients[$name] );
1374
1375 update_option( 'cmplz_transients', $transients, false );
1376 $value = false;
1377 }
1378 }
1379 return $value;
1380 }
1381 }
1382
1383 if ( !function_exists('cmplz_delete_transient') ) {
1384 /**
1385 * We user our own transient, as the wp transient is not always persistent
1386 *
1387 * @param string $name
1388 *
1389 * @return void
1390 */
1391 function cmplz_delete_transient( string $name ): void {
1392 $transients = get_option( 'cmplz_transients', array() );
1393 if ( !is_array( $transients ) ) {
1394 $transients = array();
1395 }
1396
1397 if (isset($transients[$name])) {
1398 unset($transients[$name]);
1399 }
1400
1401 update_option( 'cmplz_transients', $transients, false );
1402 }
1403 }
1404 if (!function_exists('cmplz_set_transient')) {
1405 /**
1406 * We user our own transient, as the wp transient is not always persistent
1407 * Specifically made for license transients, as it stores on network level if multisite.
1408 *
1409 * @param string $name
1410 * @param mixed $value
1411 * @param int $expiration
1412 *
1413 * @return void
1414 */
1415 function cmplz_set_transient( string $name, $value, $expiration ): void {
1416
1417 $transients = get_option( 'cmplz_transients', array() );
1418 if ( ! is_array( $transients ) ) {
1419 $transients = array();
1420 }
1421
1422 $transients[ $name ] = array(
1423 'value' => $value,
1424 'expires' => time() + (int) $expiration,
1425 );
1426 update_option( 'cmplz_transients', $transients, false );
1427 }
1428 }
1429
1430 if (!function_exists('cmplz_upgrade_to_premium')) {
1431 /**
1432 * Standardization upgrade process
1433 *
1434 * @param string $url
1435 * @param bool $add_space
1436 *
1437 * @return string
1438 */
1439 function cmplz_upgrade_to_premium( $url, $add_space = true ) {
1440 $html = '<a class="cmplz-upgrade-to-premium" target="_blank" href="' . $url . '">'.__( "Upgrade", 'complianz-gdpr' ). '</a>';
1441 if ( $add_space ) {
1442 $html = '&nbsp;' . $html;
1443 }
1444 return $html;
1445 }
1446 }
1447
1448 /**
1449 * For all legal documents for the US, privacy statement, dataleaks or processing agreements, the language should always be en_US
1450 *
1451 * */
1452 add_filter( 'locale', 'cmplz_set_plugin_language', 19, 1 );
1453 if ( ! function_exists( 'cmplz_set_plugin_language' ) ) {
1454 function cmplz_set_plugin_language( $locale ) {
1455 //@todo the region can't be detected here, because the term is not defined yet.
1456 if ( isset( $_GET['clang'] ) && $_GET['clang'] === 'en' ) {
1457 $locale = 'en_US';
1458 }
1459
1460 return $locale;
1461 }
1462 }
1463
1464 /**
1465 * To make sure the US documents are loaded entirely in English on the front-end,
1466 * We check if the locale is a not en- locale, and if so, redirect with a query arg.
1467 * This allows us to recognize the page on the next page load is needing a force US language.
1468 * */
1469
1470 add_action( 'wp', 'cmplz_add_query_arg' );
1471 if ( ! function_exists( 'cmplz_add_query_arg' ) ) {
1472 function cmplz_add_query_arg() {
1473 $cmplz_lang = isset( $_GET['clang'] ) ? $_GET['clang'] : false;
1474 if ( ! $cmplz_lang && ! cmplz_is_pagebuilder_preview() ) {
1475 global $wp;
1476 $type = false;
1477
1478 $post = get_queried_object();
1479 $locale = get_locale();
1480
1481 //if the locale is english, don't add any query args.
1482 if ( strpos( $locale, 'en' ) !== false ) {
1483 return;
1484 }
1485
1486 if ( $post && property_exists( $post, 'post_content' ) ) {
1487 $pattern = '/cmplz-document.*type=".*?".*region="(.*?)"/i';
1488 $pattern_gutenberg = '/<!-- wp:complianz\/document {.*?"selectedDocument":"[^\"](.*?)\".*?} \/-->/i';
1489 if ( preg_match_all( $pattern, $post->post_content, $matches,
1490 PREG_PATTERN_ORDER )
1491 ) {
1492 if ( isset( $matches[1][0] ) ) {
1493 $type = $matches[1][0];
1494 }
1495 } elseif ( preg_match_all( $pattern_gutenberg,
1496 $post->post_content, $matches, PREG_PATTERN_ORDER )
1497 ) {
1498 if ( isset( $matches[1][0] ) ) {
1499 $type = $matches[1][0];
1500 }
1501 }
1502
1503 if ( strpos( $type, 'us' ) !== false
1504 || strpos( $type, 'uk' ) !== false
1505 || strpos( $type, 'au' ) !== false
1506 ) {
1507 //remove lang property, add our own.
1508 wp_redirect( home_url( add_query_arg( 'clang', 'en',
1509 remove_query_arg( 'lang', $wp->request ) ) ) );
1510 exit;
1511 }
1512 }
1513
1514 }
1515 }
1516 }
1517
1518 if ( !function_exists('cmplz_has_recommended_phpversion')) {
1519 function cmplz_has_recommended_phpversion(){
1520 if (version_compare(PHP_VERSION, '7.2','>=')) {
1521 return true;
1522 } else {
1523 return false;
1524 }
1525 }
1526 }
1527
1528 if ( ! function_exists( 'cmplz_array_filter_multidimensional' ) ) {
1529 function cmplz_array_filter_multidimensional( $array, $filter_key, $filter_value ): array {
1530 return array_filter( $array,
1531 static function ( $var ) use ( $filter_value, $filter_key ) {
1532 return isset( $var[ $filter_key ] ) && $var[ $filter_key ] === $filter_value;
1533 } );
1534 }
1535 }
1536
1537 if ( ! function_exists( 'cmplz_is_amp' ) ) {
1538 /**
1539 * Check if we're on AMP, and AMP integration is active
1540 * Function should be run not before the 'wp' hook!
1541 *
1542 * @return bool
1543 */
1544 function cmplz_is_amp() {
1545
1546 $amp_on = false;
1547
1548 if ( !$amp_on && function_exists( 'ampforwp_is_amp_endpoint' ) ) {
1549 $amp_on = ampforwp_is_amp_endpoint();
1550 }
1551
1552 if ( !$amp_on && function_exists( 'is_amp_endpoint' ) ) {
1553 $amp_on = is_amp_endpoint();
1554 }
1555
1556 if ( $amp_on ) {
1557 $amp_on = cmplz_amp_integration_active();
1558 }
1559
1560 return $amp_on;
1561 }
1562 }
1563
1564 if ( ! function_exists( 'cmplz_is_amp_endpoint' ) ) {
1565 /**
1566 * Check if the site is loading as AMP
1567 * Function should be run not before the 'wp' hook!
1568 *
1569 * @return bool
1570 */
1571 function cmplz_is_amp_endpoint() {
1572
1573 $amp_on = false;
1574
1575 if ( !$amp_on && function_exists( 'ampforwp_is_amp_endpoint' ) ) {
1576 $amp_on = ampforwp_is_amp_endpoint();
1577 }
1578
1579 if ( !$amp_on && function_exists( 'is_amp_endpoint' ) ) {
1580 $amp_on = is_amp_endpoint();
1581 }
1582
1583 return $amp_on;
1584 }
1585 }
1586
1587 if ( ! function_exists( 'cmplz_amp_integration_active' ) ) {
1588 /**
1589 * Check if AMP integration is active
1590 *
1591 * @return bool
1592 */
1593 function cmplz_amp_integration_active() {
1594 return cmplz_is_integration_enabled( 'amp' );
1595 }
1596 }
1597
1598
1599 if ( ! function_exists( 'cmplz_allowed_html' ) ) {
1600 function cmplz_allowed_html() {
1601
1602 $allowed_tags = array(
1603 'a' => array(
1604 'class' => [],
1605 'href' => [],
1606 'rel' => [],
1607 'title' => [],
1608 'target' => [],
1609 'id' => [],
1610 ),
1611 'button' => array(
1612 'id' => [],
1613 'class' => [],
1614 'href' => [],
1615 'rel' => [],
1616 'title' => [],
1617 'target' => [],
1618 'aria-expanded' => [],
1619 'aria-controls' => [],
1620 ),
1621 'b' => [],
1622 'br' => [],
1623 'blockquote' => array(
1624 'cite' => [],
1625 ),
1626 'div' => array(
1627 'class' => [],
1628 'id' => [],
1629 ),
1630 'h1' => [],
1631 'h2' => array(),
1632 'h3' => [],
1633 'h4' => [],
1634 'h5' => [],
1635 'h6' => [],
1636 'i' => [],
1637 'input' => array(
1638 'type' => [],
1639 'class' => [],
1640 'name' => [],
1641 'id' => [],
1642 'required' => [],
1643 'value' => [],
1644 'placeholder' => [],
1645 'data-category' => [],
1646 'data-service' => [],
1647 'style' => array(
1648 'color' => [],
1649 ), ),
1650 'img' => array(
1651 'alt' => [],
1652 'class' => [],
1653 'height' => [],
1654 'src' => [],
1655 'width' => [],
1656 ),
1657 'label' => array(
1658 'for' => [],
1659 'class' => [],
1660 'style' => array(
1661 'visibility' => [],
1662 ),
1663 ),
1664 'li' => array(
1665 'class' => [],
1666 'id' => [],
1667 ),
1668 'ol' => array(
1669 'class' => [],
1670 'id' => [],
1671 ),
1672 'p' => array(
1673 'class' => [],
1674 'id' => [],
1675 ),
1676 'span' => array(
1677 'class' => [],
1678 'title' => [],
1679 'style' => array(
1680 'color' => [],
1681 'display' => [],
1682 ),
1683 'id' => [],
1684 ),
1685 'strong' => [],
1686 'table' => array(
1687 'class' => [],
1688 'id' => [],
1689 ),
1690 'tr' => [],
1691 'details' => array(
1692 'class' => [],
1693 'id' => [],
1694 ),
1695 'summary' => array(
1696 'class' => [],
1697 'id' => [],
1698 ),
1699 'svg' => array(
1700 'width' => [],
1701 'height' => [],
1702 'viewBox' => [],
1703 ),
1704 'polyline' => array(
1705 'points' => [],
1706 ),
1707 'path' => array(
1708 'd' => [],
1709
1710 ),
1711 'style' => [],
1712 'ul' => array(
1713 'class' => [],
1714 'id' => [],
1715 ),
1716 'form' => array(
1717 'id' => [],
1718 ),
1719 );
1720
1721 return apply_filters( "cmplz_allowed_html", $allowed_tags );
1722 }
1723 }
1724
1725 if ( ! function_exists( 'cmplz_placeholder' ) ) {
1726 /**
1727 * Get placeholder for any type of blocked content
1728 *
1729 * @param bool|string $type
1730 * @param string $src
1731 *
1732 * @return string url
1733 *
1734 * @since 2.1.0
1735 */
1736 function cmplz_placeholder( $type = false, $src = '' ) {
1737 if ( ! $type ) {
1738 $type = cmplz_get_service_by_src( $src );
1739 }
1740 $new_src = cmplz_default_placeholder( $type );
1741 $new_src = apply_filters( "cmplz_placeholder_$type", $new_src, $src );
1742 $new_src = apply_filters( 'cmplz_placeholder', $new_src, $type, $src );
1743 return $new_src;
1744 }
1745 }
1746
1747 if ( ! function_exists( 'cmplz_count_socialmedia' ) ) {
1748 /**
1749 * count the number of social media used on the site
1750 *
1751 * @return int
1752 */
1753 function cmplz_count_socialmedia() {
1754 $sm = cmplz_get_option( 'socialmedia_on_site' );
1755 if ( ! $sm ) {
1756 return 0;
1757 }
1758 if ( ! is_array( $sm ) ) {
1759 return 1;
1760 }
1761
1762 return count( array_filter( $sm ) );
1763 }
1764 }
1765
1766
1767 if ( ! function_exists( 'cmplz_download_to_site' ) ) {
1768 /**
1769 * Download a placeholder from youtube or video to this website
1770 *
1771 * @param string $src
1772 * @param bool|string $id
1773 * @param bool $use_filename //some filenames are too long to use.
1774 *
1775 * @return string url
1776 *
1777 *
1778 * @since 2.1.5
1779 */
1780 function cmplz_download_to_site( $src, $id = false, $use_filename = true ) {
1781 if ( strpos( $src, "https://" ) === false
1782 && strpos( $src, "http://" ) === false
1783 ) {
1784 $src = str_replace( '//', 'https://', $src );
1785 }
1786 if ( ! $id ) {
1787 $id = time();
1788 }
1789 require_once( ABSPATH . 'wp-admin/includes/file.php' );
1790 $upload_dir = cmplz_upload_dir('placeholders');
1791
1792 //set the path
1793 $filename = $use_filename ? "-" . basename( $src ) : '.jpg';
1794 $file = $upload_dir . $id . $filename;
1795
1796 //set the url
1797 $new_src = cmplz_upload_url( "placeholders") . $id.$filename;
1798 //download file
1799 $tmpfile = download_url( $src, $timeout = 25 );
1800
1801 //check for errors
1802 if ( is_wp_error( $tmpfile ) ) {
1803 $new_src = cmplz_default_placeholder();
1804 } else {
1805 //remove current file
1806 if ( file_exists( $file ) ) {
1807 unlink( $file );
1808 }
1809
1810 //in case the server prevents deletion, we check it again.
1811 if ( ! file_exists( $file ) ) {
1812 copy( $tmpfile, $file );
1813 }
1814 }
1815
1816 if ( is_string( $tmpfile ) && file_exists( $tmpfile ) ) {
1817 unlink( $tmpfile );
1818 } // must unlink afterwards
1819
1820 if ( file_exists( $file ) ) {
1821 try {
1822 $new_src = cmplz_create_webp( $file, $new_src );
1823 } catch ( Exception $e ) {
1824 if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
1825 error_log( $e->getMessage() );
1826 }
1827 }
1828 }
1829
1830 if ( ! file_exists( $file ) ) {
1831 return cmplz_default_placeholder();
1832 }
1833
1834 return $new_src;
1835 }
1836 }
1837
1838 //if (!function_exists('cmplz_create_webp')){
1839 // function cmplz_create_webp($file, $new_src) {
1840 // //check webp availability
1841 // if (
1842 // !function_exists('imagecreatefromjpeg') ||
1843 // !function_exists('imagecreatefrompng') ||
1844 // !function_exists('imagewebp') ||
1845 // !function_exists('imagedestroy') ||
1846 // !function_exists('imagepalettetotruecolor') ||
1847 // !function_exists('imagealphablending') ||
1848 // !function_exists('imagesavealpha')
1849 // ) {
1850 // return $new_src;
1851 // }
1852 //
1853 // if ( stripos( $file, '.jpeg' ) !== false || stripos( $file, '.jpg' ) !== false ) {
1854 // $webp_file = str_replace( array( ".jpeg", '.jpg' ), ".webp", $file );
1855 // $webp_new_src = str_replace( array( ".jpeg", '.jpg' ), ".webp", $new_src );
1856 // $image = imagecreatefromjpeg( $file );
1857 // imagewebp( $image, $webp_file, 80 );
1858 // imagedestroy( $image );
1859 //
1860 // return file_exists( $webp_file ) ? $webp_new_src : $new_src;
1861 // } elseif ( stripos( $file, '.png' ) !== false ) {
1862 // $webp_file = str_replace( '.png', ".webp", $file );
1863 // $webp_new_src = str_replace( '.png', ".webp", $new_src );
1864 // $image = imagecreatefrompng( $file );
1865 // imagepalettetotruecolor( $image );
1866 // imagealphablending( $image, true );
1867 // imagesavealpha( $image, true );
1868 // imagewebp( $image, $webp_file, 80 );
1869 // imagedestroy( $image );
1870 //
1871 // return file_exists( $webp_file ) ? $webp_new_src : $new_src;
1872 // } else {
1873 // return $new_src;
1874 // }
1875 //
1876 // }
1877 //}
1878
1879 if (!function_exists('cmplz_create_webp')){
1880
1881 function cmplz_create_webp($file, $new_src) {
1882 switch ( $file ) {
1883 case strpos( $file, '.jpeg' )!==false:
1884 case strpos( $file, '.jpg' )!==false:
1885 $ext = array(".jpeg", '.jpg');
1886 break;
1887 case strpos( $file, 'png' )!==false:
1888 $ext = '.png';
1889 break;
1890 default:
1891 return $new_src;
1892 }
1893 //@todo: new filename is returned by save, so can be used for output instead of brute force extension replace.
1894 $webp_file = str_replace( $ext, ".webp", $file );
1895 $webp_new_src = str_replace( $ext, ".webp", $new_src );
1896 $image = wp_get_image_editor($file);
1897 $result = $image->save($webp_file, 'image/webp');
1898 if ( is_wp_error( $result ) ) {
1899 return $new_src;
1900 }
1901
1902 return file_exists($webp_file) ? $webp_new_src : $new_src;
1903 }
1904 }
1905
1906 if ( ! function_exists( 'cmplz_used_cookies' ) ) {
1907 function cmplz_used_cookies() {
1908 $services_template = cmplz_get_template( 'cookiepolicy/services.php' );
1909 $cookies_row = cmplz_get_template( 'cookiepolicy/cookies_row.php' );
1910 $purpose_row = cmplz_get_template( 'cookiepolicy/purpose_row.php' );
1911 $language = substr( get_locale(), 0, 2 );
1912 $args = array(
1913 'language' => $language,
1914 'showOnPolicy' => true,
1915 'hideEmpty' => true,
1916 'ignored' => false
1917 );
1918
1919 if ( cmplz_get_option( 'wp_admin_access_users' ) === 'yes' ) {
1920 $args['isMembersOnly'] = 'all';
1921 }
1922
1923 $cookies = COMPLIANZ::$banner_loader->get_cookies_by_service( $args );
1924 $use_cdb_links = cmplz_get_option( 'use_cdb_links' ) === 'yes';
1925 $consent_per_service = cmplz_get_option( 'consent_per_service' ) === 'yes';
1926 $cookie_list = COMPLIANZ::$cookie_blocker->cookie_list;
1927
1928 $google_fonts = new CMPLZ_SERVICE('Google Fonts');
1929 $servicesHTML = '';
1930 foreach ( $cookies as $serviceID => $serviceData ) {
1931 $service = new CMPLZ_SERVICE( $serviceID, substr( get_locale(), 0, 2 ) );
1932 //if google fonts is self hosted, don't include in the cookie policy
1933 if ( cmplz_get_option('self_host_google_fonts') === 'yes'
1934 && defined('CMPLZ_SELF_HOSTED_PLUGIN_ACTIVE')
1935 && ($serviceID == $google_fonts->ID || $service->isTranslationFrom == $google_fonts->ID) ) {
1936 continue;
1937 }
1938 if ( isset($cookie_list['marketing'][COMPLIANZ::$cookie_blocker->sanitize_service_name($service->name)]) ){
1939 $topCategory = 'marketing';
1940 } else if ( isset($cookie_list['statistics'][COMPLIANZ::$cookie_blocker->sanitize_service_name($service->name)]) ) {
1941 $topCategory = 'statistics';
1942 } else if ( isset($cookie_list['preferences'][COMPLIANZ::$cookie_blocker->sanitize_service_name($service->name)]) ) {
1943 $topCategory = 'preferences';
1944 } else {
1945 $topCategory = 'functional';
1946 }
1947
1948 $serviceCheckboxClass = $consent_per_service ? '' : 'cmplz-hidden';
1949 $has_empty_cookies = false;
1950 $allPurposes = array();
1951 $cookieHTML = "";
1952
1953 foreach ( $serviceData as $purpose => $service_cookies ) {
1954 $cookies_per_purpose_HTML = "";
1955 foreach ( $service_cookies as $cookie ) {
1956 $has_empty_cookies = $has_empty_cookies || strlen( $cookie->retention ) == 0;
1957 $link_open = $link_close = '';
1958
1959 if ( $use_cdb_links && strlen( $cookie->slug ) !== 0 ) {
1960 $service_slug = ( empty($service->slug) ) ? 'unknown-service' : $service->slug;
1961 $link_open
1962 = '<a target="_blank" rel="noopener noreferrer nofollow" href="https://cookiedatabase.org/cookie/'
1963 . $service_slug . '/' . trailingslashit($cookie->slug)
1964 . '">';
1965 $link_close = '</a>';
1966 }
1967 $cookie_function = apply_filters('cmplz_cookie_function', ucfirst( $cookie->cookieFunction ), $cookie );
1968
1969 $cookies_per_purpose_HTML .= str_replace( array(
1970 '{name}',
1971 '{retention}',
1972 '{cookieFunction}',
1973 '{link_open}',
1974 '{link_close}'
1975 ), array(
1976 $cookie->name,
1977 $cookie->retention,
1978 $cookie_function,
1979 $link_open,
1980 $link_close
1981 ), $cookies_row );
1982 }
1983 $cookieHTML .= str_replace( array( '{purpose}', '{cookies_per_purpose}' ), array( $purpose, $cookies_per_purpose_HTML ), $purpose_row );
1984 $allPurposes[] = $purpose;
1985 }
1986
1987 $service_name = $service->name;
1988 if ( !$service->ID || empty( $service_name ) ){
1989 $service_name = __( 'Miscellaneous', 'complianz-gdpr' );
1990 $serviceCheckboxClass = 'cmplz-hidden';
1991 }
1992
1993 $sharing = '';
1994 if ( $service_name === 'Complianz' ) {
1995 $link = '<a target="_blank" rel="noopener noreferrer" href="https://complianz.io/legal/privacy-statement/">';
1996 $sharing = __( 'This data is not shared with third parties.', 'complianz-gdpr' )
1997 .'&nbsp;'
1998 . cmplz_sprintf( __( 'For more information, please read the %s%s Privacy Statement%s.', 'complianz-gdpr' ), $link, $service_name, '</a>' );
1999 } else if ( $service->sharesData ) {
2000 $attributes = "noopener noreferrer nofollow";
2001 if ( $service->privacyStatementURL !== '' ) {
2002 $link = '<a target="_blank" rel="'.$attributes.'" href="' . $service->privacyStatementURL . '">';
2003 $sharing = cmplz_sprintf( __( 'For more information, please read the %s%s Privacy Statement%s.', 'complianz-gdpr' ), $link, $service_name, '</a>' );
2004 }
2005 } elseif ( !empty( $service->name ) ) { //don't state sharing info on misc services
2006 $sharing = __( 'This data is not shared with third parties.', 'complianz-gdpr' );
2007 } else {
2008 $sharing = __( 'Sharing of data is pending investigation', 'complianz-gdpr' );
2009 }
2010 $purposeDescription = ( ( !empty( $service_name ) ) && ( !empty( $service->serviceType ) ) )
2011 ? cmplz_sprintf( _x( "We use %s for %s.", 'Legal document cookie policy', 'complianz-gdpr' ), $service_name, $service->serviceType ) : '';
2012
2013 if ( $use_cdb_links
2014 && !empty( $service->slug )
2015 && $service->slug !== 'unknown-service'
2016 ) {
2017 // Create descriptive link text that explains what the link is for
2018 $link_text = cmplz_sprintf( __( 'Read more about %s', 'complianz-gdpr' ), $service_name );
2019 $aria_label = cmplz_sprintf( __( 'Read more about %s service on Cookie Database', 'complianz-gdpr' ), $service_name );
2020
2021 $link_open = '<a target="_blank" rel="noopener noreferrer nofollow" href="https://cookiedatabase.org/service/' . $service->slug . '/" aria-label="' . esc_attr( $aria_label ) . '">';
2022 $purposeDescription .= ' ' . $link_open . $link_text . '</a>';
2023 }
2024 if ( count($allPurposes)>1 ){
2025 $p_key = array_search(__( 'Purpose pending investigation', 'complianz-gdpr' ), $allPurposes);
2026 if ($p_key!==false) unset($allPurposes[$p_key]);
2027 }
2028
2029 $allPurposes = implode (", ", $allPurposes);
2030 $service_slug = str_replace(' ', '-', strtolower($service_name));
2031
2032 $servicesHTML .= str_replace( array(
2033 '{service}',
2034 '{service_slug}',
2035 '{sharing}',
2036 '{purposeDescription}',
2037 '{cookies}',
2038 '{allPurposes}',
2039 '{serviceCheckboxClass}',
2040 '{topCategory}'
2041 ), array(
2042 $service_name,
2043 $service_slug,
2044 $sharing,
2045 $purposeDescription,
2046 $cookieHTML,
2047 $allPurposes,
2048 $serviceCheckboxClass,
2049 $topCategory
2050 ), $services_template );
2051 }
2052
2053 $servicesHTML = '<div id="cmplz-cookies-overview">'.$servicesHTML.'</div>';
2054
2055 return str_replace( '{plugin_url}',CMPLZ_URL, $servicesHTML);
2056 }
2057 }
2058
2059 if (!function_exists('cmplz_has_consent')) {
2060 /**
2061 * @param string $category
2062 *
2063 * @return bool
2064 */
2065 function cmplz_has_consent( $category ) {
2066 $consent_type = apply_filters( 'cmplz_user_consenttype', COMPLIANZ::$company->get_default_consenttype() );
2067 $prefix = COMPLIANZ::$banner_loader->get_cookie_prefix();
2068 $cookie_name = "{$prefix}{$category}";
2069 if ( ! $consent_type ) {
2070 // If consent_type is not set, there's no consent management, we should
2071 // return true to activate all cookies.
2072 $has_consent = true;
2073 } elseif ( strpos( $consent_type, 'optout' ) !== false && (!isset( $_COOKIE[ $cookie_name ] )) ) {
2074 // If it's opt out and no cookie is set or it's false, we should also return true.
2075 $has_consent = true;
2076 } elseif ( isset( $_COOKIE[ $cookie_name ] ) && 'allow' === $_COOKIE[ $cookie_name ] ) {
2077 // All other situations, return only true if value is allow.
2078 $has_consent = true;
2079 } else {
2080 $has_consent = false;
2081 }
2082
2083 return apply_filters( 'cmplz_has_consent', $has_consent, $category );
2084 }
2085 }
2086
2087 if (!function_exists('cmplz_has_service_consent')) {
2088 /**
2089 * Check if a service has consent
2090 *
2091 * @param string $service
2092 *
2093 * @return bool
2094 *
2095 */
2096 function cmplz_has_service_consent( $service ) {
2097 $consent_type = apply_filters( 'cmplz_user_consenttype', COMPLIANZ::$company->get_default_consenttype() );
2098 $prefix = COMPLIANZ::$banner_loader->get_cookie_prefix();
2099 $cookie_name = "{$prefix}consented_services";
2100 $consented_services = isset($_COOKIE[ $cookie_name ]) ? json_decode(stripslashes($_COOKIE[ $cookie_name ])) : false;
2101 if ( ! $consent_type ) {
2102 // If consent_type is not set, there's no consent management, we should
2103 // return true to activate all cookies.
2104 $has_consent = true;
2105 } elseif ( strpos( $consent_type, 'optout' ) !== false ) {
2106 // If it's opt out there's no consent per service, we should also return true.
2107 $has_consent = true;
2108 } elseif ( $consented_services && property_exists( $consented_services, $service ) && 1 == $consented_services->{$service} ) {
2109 // All other situations, return only true if value is allow.
2110 $has_consent = true;
2111 } else {
2112 $has_consent = false;
2113 }
2114
2115 return apply_filters( 'cmplz_has_service_consent', $has_consent, $service );
2116 }
2117 }
2118
2119 /**
2120 * Check if this field is translatable
2121 *
2122 * @param $fieldname
2123 *
2124 * @return bool
2125 */
2126
2127 if ( ! function_exists( 'cmplz_translate' ) ) {
2128 function cmplz_translate( $value, $fieldname ) {
2129 if ( function_exists( 'pll__' ) ) {
2130 $value = pll__( $value );
2131 }
2132
2133 if ( function_exists( 'icl_translate' ) ) {
2134 $value = icl_translate( 'complianz', $fieldname, $value );
2135 }
2136
2137 $value = apply_filters( 'wpml_translate_single_string', $value, 'complianz', $fieldname );
2138
2139 return $value;
2140
2141 }
2142 }
2143
2144 if ( !function_exists('cmplz_get_server') ) {
2145 /**
2146 * Get server type
2147 *
2148 * @return string
2149 */
2150
2151 function cmplz_get_server() {
2152 $server_raw = strtolower( sanitize_text_field($_SERVER['SERVER_SOFTWARE']) );
2153 //figure out what server they're using
2154 if ( strpos( $server_raw, 'apache' ) !== false ) {
2155 return 'Apache';
2156 } elseif ( strpos( $server_raw, 'nginx' ) !== false ) {
2157 return 'NGINX';
2158 } elseif ( strpos( $server_raw, 'litespeed' ) !== false ) {
2159 return 'LiteSpeed';
2160 } else { //unsupported server
2161 return 'Not recognized';
2162 }
2163 }
2164 }
2165
2166 if (!function_exists('cmplz_sanitize_category')) {
2167 function cmplz_sanitize_category($category){
2168 $cats = ['functional','preferences', 'statistics', 'marketing'];
2169 if ( !in_array( $category, $cats, true ) ) {
2170 $category = 'marketing';
2171 }
2172 return $category;
2173 }
2174 }
2175
2176 if (!function_exists('cmplz_sanitize_consenttype')) {
2177 function cmplz_sanitize_consenttype($consenttype){
2178 $types = ['optin','optout', 'other', 'optinstats'];//optinstats might be used by wp consent api
2179 if ( !in_array( $consenttype, $types, true ) ) {
2180 $consenttype = 'other';
2181 }
2182 return $consenttype;
2183 }
2184 }
2185
2186 /**
2187 * Show a reference to cookiedatabase if user has accepted the API
2188 *
2189 * @return bool
2190 */
2191
2192 if ( ! function_exists( 'cmplz_cdb_reference_in_policy' ) ) {
2193 function cmplz_cdb_reference_in_policy() {
2194 $use_reference = COMPLIANZ::$banner_loader->use_cdb_api();
2195 return apply_filters( 'cmplz_use_cdb_reference', $use_reference );
2196 }
2197 }
2198
2199 /**
2200 * Register a translation
2201 *
2202 * @param $fieldname
2203 *
2204 * @return bool
2205 */
2206
2207 if ( ! function_exists( 'cmplz_register_translation' ) ) {
2208
2209 function cmplz_register_translation( $string, $fieldname ) {
2210 if ( ! is_string( $string ) || !is_string($fieldname) ) {
2211 return;
2212 }
2213 //polylang
2214 if ( function_exists( "pll_register_string" ) ) {
2215 pll_register_string( $fieldname, $string, 'complianz' );
2216 }
2217
2218 //wpml
2219 if ( function_exists( 'icl_register_string' ) ) {
2220 icl_register_string( 'complianz', $fieldname, $string );
2221 }
2222
2223 do_action( 'wpml_register_single_string', 'complianz', $fieldname, $string );
2224
2225 }
2226 }
2227
2228 if ( ! function_exists( 'cmplz_default_placeholder' ) ) {
2229 /**
2230 * Return the default placeholder image
2231 *
2232 * @return string placeholder
2233 * @since 2.1.5
2234 */
2235 function cmplz_default_placeholder( $type = 'default' ) {
2236 //treat open streetmaps same as google maps.
2237 if ( $type === 'openstreetmaps' ) {
2238 $type = 'google-maps';
2239 }
2240
2241 $style = cmplz_get_option('placeholder_style');
2242 $ratio = $type === 'google-maps' ? cmplz_get_option( 'google-maps-format' ) : '';
2243 $path = CMPLZ_PATH . "assets/images/placeholders";
2244 //check if this type exists as placeholder
2245 if ( file_exists( "$path/$type-$style-$ratio.jpg" ) ) {
2246 $img = "$type-$style-$ratio.jpg";
2247 } else if ( file_exists( "$path/$type-$style.jpg" ) ) {
2248 $img = "$type-$style.jpg";
2249 } else {
2250 $img = "default-$style.jpg";
2251 }
2252
2253 $img_url = CMPLZ_URL . 'assets/images/placeholders/' . $img;
2254
2255 //check for image in themedir/complianz-gpdr-premium
2256 $theme_img = trailingslashit( get_stylesheet_directory() ) . trailingslashit( basename( CMPLZ_PATH ) ) . $img;
2257 if ( file_exists( $theme_img ) ) {
2258 $img_url = trailingslashit( get_stylesheet_directory_uri() ) . trailingslashit( basename( CMPLZ_PATH ) ) . $img;
2259 }
2260
2261 return apply_filters( 'cmplz_default_placeholder', $img_url, $type, $style );
2262 }
2263 }
2264
2265 if ( ! function_exists( 'cmplz_get_document_url' ) ) {
2266 /**
2267 * Get url to legal document
2268 *
2269 * @param string $region
2270 *
2271 * @return string URL
2272 */
2273
2274 function cmplz_get_document_url( $type, $region = 'eu' ) {
2275 return COMPLIANZ::$document->get_page_url( $type, $region );
2276 }
2277 }
2278
2279 if ( ! function_exists( 'cmplz_remote_file_exists' ) ) {
2280 /**
2281 * Check if a remote file exists
2282 *
2283 * @param string $url
2284 *
2285 * @return bool
2286 */
2287
2288 function cmplz_remote_file_exists( string $url ): bool {
2289 if ( empty($url) ) {
2290 return false;
2291 }
2292
2293 try {
2294 $headers = @get_headers($url);
2295 if ($headers === false) {
2296 // URL is not accessible or some error occurred
2297 return false;
2298 }
2299
2300 // Check if the HTTP status code starts with "200" (indicating success)
2301 return strpos($headers[0], '200') !== false;
2302
2303 } catch (Exception $e) {
2304
2305 }
2306
2307 return false;
2308 }
2309
2310 }
2311
2312 if ( ! function_exists( 'cmplz_detected_firstparty_marketing' )) {
2313
2314 /**
2315 * Check if we detect first party marketing scripts
2316 * @return bool
2317 */
2318
2319 function cmplz_detected_firstparty_marketing(){
2320 global $cmplz_integrations_list;
2321 $active_plugins = array();
2322 foreach ( $cmplz_integrations_list as $plugin => $details ) {
2323 if ( cmplz_integration_plugin_is_enabled( $plugin ) ) {
2324 $active_plugins[$plugin] = $details;
2325 }
2326 }
2327 $firstparty_plugins = array_filter(array_column($active_plugins, 'firstparty_marketing'));
2328
2329 return count($firstparty_plugins)>0;
2330 }
2331 }
2332
2333 if ( ! function_exists( 'cmplz_uses_gutenberg' ) ) {
2334 function cmplz_uses_gutenberg() {
2335
2336 if ( function_exists( 'has_block' )
2337 && !class_exists( 'Classic_Editor', false )
2338 ) {
2339 return true;
2340 }
2341
2342 return false;
2343 }
2344 }
2345
2346 if ( ! function_exists( 'cmplz_get_used_consenttypes' ) ) {
2347 /**
2348 * Get list of consenttypes in use on this site, based on the selected regions
2349 * @param bool $add_labels
2350 * @return array consenttypes
2351 */
2352 function cmplz_get_used_consenttypes( $add_labels = false ) {
2353 //get all regions in use on this site
2354 $regions = cmplz_get_regions();
2355 //if manuanl override detected, add that region's consenttype here.
2356 $consent_types = array();
2357 //for each region, get the consenttype
2358 foreach ( $regions as $region ) {
2359 if ( ! isset( COMPLIANZ::$config->regions[ $region ]['type'] ) ) {
2360 continue;
2361 }
2362 $consent_types[] = apply_filters( 'cmplz_consenttype', COMPLIANZ::$config->regions[ $region ]['type'], $region );
2363 }
2364
2365 //there's no way we can simply find the consenttype for the manually added region, due to fallback complexity. So we add all of them in that case.
2366 if ( isset( $_GET['cmplz_user_region']) ) {
2367 $consent_types[] = 'optin';
2368 $consent_types[] = 'optout';
2369 }
2370
2371 //remove duplicates
2372 $consent_types = array_unique( $consent_types );
2373 if ( $add_labels ) {
2374 $consent_types_labelled = array();
2375 foreach ( $consent_types as $consent_type ) {
2376 $consent_types_labelled[$consent_type] = cmplz_consenttype_nicename($consent_type);
2377 }
2378 $consent_types = $consent_types_labelled;
2379 }
2380
2381 return $consent_types;
2382 }
2383 }
2384
2385 if ( ! function_exists( 'cmplz_short_date_format') ) {
2386 /**
2387 * Make sure the date formate is always the short version. If "F" (February) is used, replace with "M" (Feb)
2388 * @return string
2389 */
2390 function cmplz_short_date_format(){
2391 return str_replace( array('F', 'Y'), array('M', 'y'), get_option( 'date_format' ) );
2392 }
2393 }
2394
2395 if ( ! function_exists( 'cmplz_uses_preferences_cookies' ) ) {
2396
2397 /**
2398 * Check if the site uses preferences cookies
2399 *
2400 * @return bool
2401 */
2402 function cmplz_uses_preferences_cookies()
2403 {
2404 return cmplz_consent_mode() || cmplz_consent_api_active() || cmplz_get_option( 'consent_per_service' ) === 'yes';
2405 }
2406 }
2407
2408 if ( ! function_exists( 'cmplz_uses_statistic_cookies' ) ) {
2409
2410 /**
2411 * Check if the site uses statistic cookies
2412 *
2413 * @return bool
2414 */
2415 function cmplz_uses_statistic_cookies()
2416 {
2417 return cmplz_get_option( 'compile_statistics' ) !== 'no' || cmplz_uses_thirdparty('vimeo');
2418 }
2419 }
2420
2421 if ( ! function_exists( 'cmplz_uses_marketing_cookies' ) ) {
2422
2423 /**
2424 * Check if the site uses marketing cookies
2425 *
2426 * @return bool
2427 */
2428 function cmplz_uses_marketing_cookies() {
2429
2430 $uses_marketing_cookies
2431 = cmplz_get_option( 'uses_ad_cookies' ) === 'yes'
2432 || cmplz_get_option( 'uses_firstparty_marketing_cookies' ) === 'yes'
2433 || cmplz_get_option( 'uses_thirdparty_services' ) === 'yes'
2434 || cmplz_get_option( 'uses_social_media' ) === 'yes';
2435
2436 return apply_filters( 'cmplz_uses_marketing_cookies', $uses_marketing_cookies );
2437 }
2438 }
2439
2440
2441
2442 if ( ! function_exists( 'cmplz_impressum_required' ) ) {
2443
2444 /**
2445 * Check if the site requires an impressum
2446 *
2447 * @return bool
2448 */
2449 function cmplz_impressum_required() {
2450 return cmplz_get_option( 'eu_consent_regions' ) === 'yes' && cmplz_get_option( 'impressum' ) !== 'none' ;
2451 }
2452 }
2453
2454 if ( ! function_exists( 'cmplz_uses_optin' ) ) {
2455
2456 /**
2457 * Check if the site uses one of the optin types
2458 *
2459 * @return bool
2460 */
2461 function cmplz_uses_optin() {
2462 $regions = cmplz_get_regions();
2463 //ensure a default in case of no regions, to prevent weird cookie banner wysiwyg issues.
2464 if (count($regions)===0) {
2465 return true;
2466 }
2467 return ( in_array( 'optin', cmplz_get_used_consenttypes() )
2468 || in_array( 'optinstats', cmplz_get_used_consenttypes() ) );
2469 }
2470 }
2471
2472
2473 if ( ! function_exists( 'cmplz_has_only_functional_category' ) ) {
2474 /**
2475 * Check if the site only has functional cookies available
2476 * This means no marketing, statistics, or preferences cookies are used
2477 *
2478 * @return bool
2479 */
2480 function cmplz_has_only_functional_category() {
2481 // Check if any other categories besides functional are used
2482 $uses_marketing = cmplz_uses_marketing_cookies();
2483 $uses_statistics = cmplz_uses_statistic_cookies();
2484 $uses_preferences = cmplz_uses_preferences_cookies();
2485
2486 // If none of the other categories are used, only functional is available
2487 return !$uses_marketing && !$uses_statistics && !$uses_preferences;
2488 }
2489 }
2490
2491 if ( ! function_exists( 'cmplz_uses_optout' ) ) {
2492 function cmplz_uses_optout() {
2493 return ( in_array( 'optout', cmplz_get_used_consenttypes() ) );
2494 }
2495 }
2496
2497 if ( ! function_exists( 'cmplz_ab_testing_enabled' ) ) {
2498 function cmplz_ab_testing_enabled() {
2499 return apply_filters( 'cmplz_ab_testing_enabled', false );
2500 }
2501 }
2502
2503
2504 if ( ! function_exists( 'cmplz_consenttype_nicename' ) ) {
2505 /**
2506 * Get nice name for consenttype
2507 *
2508 * @param string $consenttype
2509 *
2510 * @return string nicename
2511 */
2512 function cmplz_consenttype_nicename( $consenttype ) {
2513 switch ( $consenttype ) {
2514 case 'optin':
2515 return __( 'Opt-in', 'complianz-gdpr' );
2516 case 'optout':
2517 return __( 'Opt-out', 'complianz-gdpr' );
2518 default :
2519 return __( 'All consent types', 'complianz-gdpr' );
2520 }
2521 }
2522 }
2523
2524 if ( ! function_exists( 'cmplz_uses_sensitive_data' ) ) {
2525 /**
2526 * Check if site uses sensitive data
2527 *
2528 * @return bool uses_sensitive_data
2529 */
2530 function cmplz_uses_sensitive_data() {
2531 $special_data = array(
2532 'bank-account',
2533 'financial-information',
2534 'medical',
2535 'health-insurcance'
2536 );
2537 foreach ( COMPLIANZ::$config->purposes as $key => $label ) {
2538
2539 if ( ! empty( COMPLIANZ::$config->details_per_purpose_us ) ) {
2540 foreach ( $special_data as $special_data_key ) {
2541 $value = cmplz_get_option( $key . '_data_purpose_us' );
2542 if ( isset( $value[ $special_data_key ] )
2543 && $value[ $special_data_key ]
2544 ) {
2545 return true;
2546 }
2547 }
2548 }
2549
2550 }
2551
2552 return false;
2553 }
2554 }
2555
2556
2557 if ( ! function_exists( 'cmplz_get_consenttype_for_region' ) ) {
2558 /**
2559 * Get the consenttype which is used in this region
2560 *
2561 * @param string $region
2562 *
2563 * @return string consenttype
2564 */
2565 function cmplz_get_consenttype_for_region( $region ) {
2566 //fallback
2567 if ( ! isset( COMPLIANZ::$config->regions[ $region ]['type'] ) ) {
2568 $consenttype = 'optin';
2569 } else {
2570 $consenttype = COMPLIANZ::$config->regions[ $region ]['type'];
2571 }
2572 return apply_filters( 'cmplz_consenttype', $consenttype, $region );
2573 }
2574 }
2575
2576 if ( ! function_exists( 'cmplz_uses_consenttype' ) ) {
2577 /**
2578 * Check if a specific consenttype is used
2579 *
2580 * @param string $check_consenttype
2581 * @param string $region
2582 *
2583 * @return bool $uses_consenttype
2584 */
2585 function cmplz_uses_consenttype( $check_consenttype, $region = false ) {
2586 if ( $region ) {
2587 //get consenttype for region
2588 $consenttype = cmplz_get_consenttype_for_region( $region );
2589 if ( $consenttype === $check_consenttype ) {
2590 return true;
2591 }
2592 } else {
2593 //check if any region has a consenttype $check_consenttype
2594 $regions = cmplz_get_regions();
2595 foreach ( $regions as $k_region ) {
2596 $consenttype = cmplz_get_consenttype_for_region( $k_region );
2597 if ( $consenttype === $check_consenttype ) {
2598 return true;
2599 }
2600 }
2601 }
2602
2603 return false;
2604 }
2605 }
2606
2607 if ( ! function_exists( 'cmplz_get_default_banner_id' ) ) {
2608
2609 /**
2610 * Get the default banner ID
2611 *
2612 * @return int default_ID
2613 */
2614 function cmplz_get_default_banner_id() {
2615 $banner_id = cmplz_get_transient('cmplz_default_banner_id');
2616 if ( !$banner_id ){
2617 if ( !get_option('cmplz_cbdb_version') ) {
2618 //table not created yet.
2619 return 0;
2620 }
2621 global $wpdb;
2622 $cookiebanners = $wpdb->get_results( "select * from {$wpdb->prefix}cmplz_cookiebanners as cb where cb.default = true" );
2623
2624 //if nothing, try the first entry
2625 if ( empty( $cookiebanners ) ) {
2626 $cookiebanners = $wpdb->get_results( "select * from {$wpdb->prefix}cmplz_cookiebanners" );
2627 }
2628
2629 if ( ! empty( $cookiebanners ) ) {
2630 $banner_id = $cookiebanners[0]->ID;
2631 }
2632 cmplz_set_transient('cmplz_default_banner_id', $banner_id, HOUR_IN_SECONDS);
2633 }
2634 return $banner_id;
2635 }
2636 }
2637
2638 if ( ! function_exists( 'cmplz_user_can_manage' ) ) {
2639 function cmplz_user_can_manage() {
2640 if ( current_user_can( apply_filters('cmplz_capability','manage_privacy') )
2641 ) {
2642 return true;
2643 }
2644
2645 return false;
2646 }
2647 }
2648
2649 if ( ! function_exists( 'cmplz_get_cookiebanners' ) ) {
2650
2651 /**
2652 * Get array of banner objects
2653 *
2654 * @param array $args
2655 *
2656 * @return array
2657 */
2658
2659 function cmplz_get_cookiebanners( $args = array() ) {
2660 $args = wp_parse_args( $args, array( 'status' => 'active' ) );
2661 $sql = '';
2662 global $wpdb;
2663
2664 if ( isset($args['ID']) ) {
2665 $sql = 'AND cdb.ID = ' . (int) $args['ID'];
2666 }
2667
2668 if ( isset( $args['default'] ) && $args['default'] === true ) {
2669 $sql = 'AND cdb.default = true LIMIT 1';
2670 }
2671 if ( isset( $args['default'] ) && $args['default'] === false ) {
2672 $sql = 'AND cdb.default = false';
2673 }
2674 if ( isset( $args['limit'] ) && $args['limit'] !== false ) {
2675 $sql = ' LIMIT ' . (int) $args['limit'];
2676 }
2677
2678 $sql_string = empty($sql) ? 'default' : sanitize_title($sql);
2679 $cookiebanners = wp_cache_get('cmplz_cookiebanners_'.$sql_string, 'complianz');
2680 if ( !$cookiebanners ){
2681 $cookiebanners = $wpdb->get_results( "select * from {$wpdb->prefix}cmplz_cookiebanners as cdb where 1=1 $sql" );
2682 wp_cache_set('cmplz_cookiebanners_'.$sql_string, $cookiebanners, 'complianz', HOUR_IN_SECONDS);
2683 }
2684
2685 return $cookiebanners;
2686 }
2687 }
2688
2689 /**
2690 * Force re-save all cookie banners to regenerate CSS and clear caches
2691 *
2692 * Used during upgrades to ensure banners render correctly with template changes.
2693 *
2694 * @return void
2695 */
2696 if ( ! function_exists( 'cmplz_resave_all_banners' ) ) {
2697 function cmplz_resave_all_banners() {
2698 $banners = cmplz_get_cookiebanners();
2699 if ( $banners ) {
2700 foreach ( $banners as $banner_item ) {
2701 $banner = new CMPLZ_COOKIEBANNER( $banner_item->ID );
2702 $banner->save();
2703 }
2704 }
2705 }
2706 }
2707
2708 if ( ! function_exists( 'cmplz_sanitize_language' ) ) {
2709
2710 /**
2711 * Validate a language string
2712 *
2713 * @param $language
2714 *
2715 * @return bool|string
2716 */
2717
2718 function cmplz_sanitize_language( $language ) {
2719 $pattern = '/^[a-zA-Z]{2}$/';
2720 if ( ! is_string( $language ) ) {
2721 return false;
2722 }
2723 $language = substr( $language, 0, 2 );
2724
2725 if ( (bool) preg_match( $pattern, $language ) ) {
2726 $language = strtolower( $language );
2727
2728 return $language;
2729 }
2730
2731 return false;
2732 }
2733 }
2734
2735
2736 if ( ! function_exists( 'cmplz_sanitize_languages' ) ) {
2737
2738 /**
2739 * Validate a languages array
2740 *
2741 * @param array $language
2742 *
2743 * @return array
2744 */
2745
2746 function cmplz_sanitize_languages( $languages ) {
2747 $output = array();
2748 foreach ( $languages as $language ) {
2749 $output[] = cmplz_sanitize_language( $language );
2750 }
2751
2752 return $output;
2753 }
2754 }
2755
2756 if ( ! function_exists( 'cmplz_remove_free_translation_files' ) ) {
2757
2758 /**
2759 * Get a list of files from a directory, with the extensions as passed.
2760 */
2761
2762 function cmplz_remove_free_translation_files() {
2763 //can't use CMPLZ_PATH here, it may not have been defined yet on activation
2764 $path = plugin_dir_path(__FILE__);
2765 $path = dirname( $path, 2 ) . "/languages/plugins/";
2766 $extensions = array( "po", "mo", "php" );
2767 if ( $handle = opendir( $path ) ) {
2768 while ( false !== ( $file = readdir( $handle ) ) ) {
2769 if ( $file != "." && $file != ".." ) {
2770 $file = $path . '/' . $file;
2771 $ext = strtolower( pathinfo( $file, PATHINFO_EXTENSION ) );
2772
2773 if ( is_file( $file ) && in_array( $ext, $extensions )
2774 && strpos( $file, 'complianz-gdpr' ) !== false
2775 && strpos( $file, 'backup' ) === false
2776 ) {
2777 unlink($file);
2778 }
2779 }
2780 }
2781 closedir( $handle );
2782 }
2783 }
2784 }
2785
2786 if ( ! function_exists( 'cmplz_has_free_translation_files' ) ) {
2787
2788 /**
2789 * Get a list of files from a directory, with the extensions as passed.
2790 *
2791 * @return bool
2792 */
2793
2794 function cmplz_has_free_translation_files() {
2795 //can't use CMPLZ_PATH here, it may not have been defined yet on activation
2796 $path = plugin_dir_path(__FILE__);
2797 $path = dirname( $path, 2 ) . "/languages/plugins/";
2798
2799 if ( ! file_exists( $path ) ) {
2800 return false;
2801 }
2802
2803 $has_free_files = false;
2804 $extensions = array( "po", "mo" );
2805 if ( $handle = opendir( $path ) ) {
2806 while ( false !== ( $file = readdir( $handle ) ) ) {
2807 if ( $file != "." && $file != ".." ) {
2808 $file = $path . '/' . $file;
2809 $ext = strtolower( pathinfo( $file, PATHINFO_EXTENSION ) );
2810
2811 if ( is_file( $file ) && in_array( $ext, $extensions )
2812 && strpos( $file, 'complianz-gdpr' ) !== false
2813 ) {
2814 $has_free_files = true;
2815 break;
2816 }
2817 }
2818 }
2819 closedir( $handle );
2820 }
2821
2822 return $has_free_files;
2823 }
2824 }
2825
2826 if (!function_exists('array_key_first')) {
2827 function array_key_first(array $array) {
2828 reset($array);
2829 return key($array);
2830 }
2831 }
2832
2833 if ( ! function_exists( 'cmplz_sprintf' ) ) {
2834 /**
2835 * Wrapper function for sprintf to prevent fatal errors when the %s variables in source and target do not match
2836 * @param string $format
2837 * @param mixed $values
2838 * @return string
2839 */
2840 function cmplz_sprintf(){
2841 $args = func_get_args();
2842 $count = substr_count($args[0], '%s');
2843 $args_count = count($args) - 1;
2844 if ( $args_count === $count ){
2845 return call_user_func_array('sprintf', $args);
2846 } else {
2847 $output = $args[0];
2848 if ( cmplz_admin_logged_in() ){
2849 $output .= '&nbsp;<a target="_blank" href="https://complianz.io/translation-error-sprintf-printf-too-few-arguments">(Translation error)</a>';
2850 }
2851 return $output;
2852 }
2853 }
2854 }
2855
2856 if ( !function_exists('cmplz_dnt_enabled') ) {
2857 /**
2858 * Premium should respect Do Not Track settings in browsers, if the user has enabled this setting.
2859 *
2860 *
2861 * */
2862 function cmplz_dnt_enabled()
2863 {
2864 //only if the user has explicitly enabled this
2865 if ( cmplz_get_option('respect_dnt') !== 'no' ) {
2866 return ( ( isset($_SERVER['HTTP_DNT']) && $_SERVER['HTTP_DNT'] == 1 ) || isset($_SERVER['HTTP_SEC_GPC']) );
2867 }
2868 return false;
2869 }
2870 }
2871
2872 if ( ! function_exists( 'cmplz_printf' ) ) {
2873 /**
2874 * Wrapper function for printf to prevent fatal errors when the %s variables in source and target do not match
2875 * @param string $format
2876 * @param mixed $values
2877 * @echo string
2878 */
2879 function cmplz_printf(){
2880 $args = func_get_args();
2881 $count = substr_count($args[0], '%s');
2882 $args_count = count($args) - 1;
2883 if ( $args_count === $count ){
2884 echo call_user_func_array('sprintf', $args);
2885 } else {
2886 $output = $args[0];
2887 if ( cmplz_admin_logged_in() ){
2888 $output .= '&nbsp;<a target="_blank" href="https://complianz.io/translation-error-sprintf-printf-too-few-arguments">(Translation error)</a>';
2889 }
2890 echo $output;
2891 }
2892 }
2893 }
2894
2895 if ( ! function_exists('cmplz_quebec_notice')) {
2896 function cmplz_quebec_notice() {
2897
2898 $text = cmplz_sprintf( __( "In September 2023 the Quebec bill 64 will be enforced in Canada. In order to keep your site compliant, %sopt-in must be implemented for Canada%s. Please Navigate to the %sWizard%s and enable opt-in for Canada.", "complianz-gdpr" ), '<strong>', '</strong>' , '<a href="' . admin_url( 'admin.php?page=cmplz-wizard&step=1' ) . '">', '</a>' ) . "<br><br>";
2899 $text .= __( "Please be aware that this will activate opt-in for Canada, altering the banner and blocking non-functional scripts and cookies prior to consent. Please check the front-end of your site after activating opt-in.", "complianz-gdpr" );
2900
2901 return $text;
2902 }
2903 }
2904
2905 if ( ! function_exists('cmplz_requires_quebec_notice') ) {
2906 function cmplz_requires_quebec_notice() {
2907
2908 if ( array_key_exists('ca', cmplz_get_regions() )
2909 && cmplz_get_option('sensitive_information_processed') !== 'yes'
2910 && cmplz_upgraded_to_current_version() ) {
2911 return true;
2912 }
2913
2914 return false;
2915
2916 }
2917 }
2918
2919
2920 if (!function_exists('cmplz_wsc_is_enabled')) {
2921 /**
2922 * Helper function to check if the wsc is enabled,
2923 * then show/hide input fields on wsc settings page.
2924 *
2925 * @return bool
2926 */
2927 function cmplz_wsc_is_enabled(): bool
2928 {
2929 $signup_status = get_option('cmplz_wsc_signup_status') === 'enabled'; // true if === "enabled"
2930
2931 return $signup_status;
2932 }
2933 }
2934
2935
2936 if ( ! function_exists('cmplz_targets_quebec') ) {
2937 function cmplz_targets_quebec() {
2938 if ( cmplz_get_option('ca_targets_quebec') === 'yes') {
2939 return true;
2940 }
2941
2942 return false;
2943 }
2944 }
2945
2946 if ( ! function_exists( 'cmplz_site_has_webshop' ) ) {
2947 /**
2948 * Check if WooCommerce or Easy Digital Downloads is active.
2949 * Plugin presence is checked directly — independent of the is_webshop wizard option,
2950 * which classifies the site legally but does not reflect whether e-commerce pages
2951 * exist and need scanning.
2952 *
2953 * @return bool
2954 */
2955 function cmplz_site_has_webshop(): bool {
2956 return class_exists( 'WooCommerce' ) || class_exists( 'Easy_Digital_Downloads' );
2957 }
2958 }
2959
2960 if ( ! function_exists( 'cmplz_site_has_custom_post_types' ) ) {
2961 /**
2962 * Check if the site has any public non-builtin custom post types registered.
2963 *
2964 * @return bool
2965 */
2966 function cmplz_site_has_custom_post_types(): bool {
2967 return ! empty( get_post_types( array( 'public' => true, '_builtin' => false ) ) );
2968 }
2969 }
2970
2971 if ( ! function_exists( 'cmplz_site_has_high_post_count' ) ) {
2972 /**
2973 * Check if the site has more than 200 published posts or pages.
2974 * Stores two transients (TTL: DAY_IN_SECONDS):
2975 * cmplz_scan_high_post_count — '1'/'0' boolean guard (avoids COUNT on every request).
2976 * cmplz_scan_post_count — raw integer count for the dynamic volume upsell title.
2977 *
2978 * @return bool
2979 */
2980 function cmplz_site_has_high_post_count(): bool {
2981 $cached = get_transient( 'cmplz_scan_high_post_count' );
2982 if ( $cached !== false ) {
2983 return $cached === '1';
2984 }
2985
2986 global $wpdb;
2987 $count = (int) $wpdb->get_var(
2988 "SELECT COUNT(*) FROM {$wpdb->posts}
2989 WHERE post_status = 'publish'
2990 AND post_type IN ('post', 'page')"
2991 );
2992
2993 $result = $count > 1000;
2994 set_transient( 'cmplz_scan_high_post_count', $result ? '1' : '0', DAY_IN_SECONDS );
2995 set_transient( 'cmplz_scan_post_count', $count, DAY_IN_SECONDS );
2996
2997 return $result;
2998 }
2999 }
3000
3001 if ( ! function_exists( 'cmplz_volume_upsell_applies' ) ) {
3002 /**
3003 * Check if the volume upsell notice should be shown.
3004 * Returns false when a higher-priority upsell (webshop or CPT) is already active.
3005 *
3006 * @return bool
3007 */
3008 function cmplz_volume_upsell_applies(): bool {
3009 if ( cmplz_site_has_webshop() || cmplz_site_has_custom_post_types() ) {
3010 return false;
3011 }
3012 return cmplz_site_has_high_post_count();
3013 }
3014 }
3015
3016
3017 if ( defined( 'cmplz_free' ) && cmplz_free ) {
3018 if ( ! function_exists( 'cmplz_invalidate_post_count_cache' ) ) {
3019 /**
3020 * Delete the high-post-count transients when a post is first published.
3021 * Clears both cmplz_scan_high_post_count and cmplz_scan_post_count.
3022 *
3023 * @param string $new New post status.
3024 * @param string $old Previous post status.
3025 * @return void
3026 */
3027 function cmplz_invalidate_post_count_cache( string $new, string $old ): void {
3028 if ( $new === 'publish' && $old !== 'publish' ) {
3029 delete_transient( 'cmplz_scan_high_post_count' );
3030 delete_transient( 'cmplz_scan_post_count' );
3031 }
3032 }
3033 }
3034 add_action( 'transition_post_status', 'cmplz_invalidate_post_count_cache', 10, 2 );
3035 }
3036