PluginProbe ʕ •ᴥ•ʔ
Cookiebot by Usercentrics – Automatic Cookie Banner for GDPR/CCPA & Google Consent Mode / 4.5.0
Cookiebot by Usercentrics – Automatic Cookie Banner for GDPR/CCPA & Google Consent Mode v4.5.0
4.7.2 4.7.1 trunk 2.3.0 2.4.0 2.4.1 2.4.2 2.5.0 3.0.0 3.0.1 3.1.0 3.10.0 3.10.1 3.11.1 3.11.2 3.11.3 3.2.0 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.6.1 3.6.2 3.6.5 3.6.6 3.7.0 3.7.1 3.8.0 3.9.0 4.0.0 4.0.1 4.0.2 4.0.3 4.1.0 4.1.1 4.2.0 4.2.1 4.2.10 4.2.11 4.2.12 4.2.13 4.2.14 4.2.2 4.2.3 4.2.4 4.2.5 4.2.6 4.2.7 4.2.8 4.2.9 4.3.0 4.3.1 4.3.10 4.3.11 4.3.12 4.3.2 4.3.3 4.3.4 4.3.5 4.3.6 4.3.7 4.3.7.1 4.3.8 4.3.9 4.3.9.1 4.4.0 4.4.1 4.4.2 4.5.0 4.5.1 4.5.10 4.5.11 4.5.2 4.5.3 4.5.4 4.5.5 4.5.6 4.5.7 4.5.8 4.5.9 4.6.0 4.6.1 4.6.2 4.6.3 4.6.4 4.6.5 4.6.6 4.6.7 4.7.0
cookiebot / src / lib / Cookiebot_WP.php
cookiebot / src / lib Last commit date
buffer 1 year ago script_loader_tag 1 year ago traits 1 year ago Account_Service.php 1 year ago Consent_API_Helper.php 1 year ago Cookie_Consent.php 1 year ago Cookie_Consent_Interface.php 1 year ago Cookiebot_Activated.php 1 year ago Cookiebot_Admin_Links.php 1 year ago Cookiebot_Automatic_Updates.php 1 year ago Cookiebot_Deactivated.php 1 year ago Cookiebot_Frame.php 1 year ago Cookiebot_Javascript_Helper.php 1 year ago Cookiebot_Review.php 1 year ago Cookiebot_WP.php 1 year ago Dependency_Container.php 1 year ago Settings_Page_Tab.php 1 year ago Settings_Service.php 1 year ago Settings_Service_Interface.php 1 year ago Supported_Languages.php 1 year ago Supported_Regions.php 1 year ago WP_Rocket_Helper.php 1 year ago Widgets.php 1 year ago global-deprecations.php 1 year ago helper.php 1 year ago
Cookiebot_WP.php
614 lines
1 <?php
2
3
4 namespace cybot\cookiebot\lib;
5
6 use cybot\cookiebot\addons\Cookiebot_Addons;
7 use cybot\cookiebot\admin_notices\Cookiebot_Notices;
8 use cybot\cookiebot\gutenberg\Cookiebot_Gutenberg_Declaration_Block;
9 use cybot\cookiebot\settings\Menu_Settings;
10 use cybot\cookiebot\settings\Network_Menu_Settings;
11 use cybot\cookiebot\shortcode\Cookiebot_Embedding_Shortcode;
12 use cybot\cookiebot\widgets\Dashboard_Widget_Cookiebot_Status;
13 use cybot\cookiebot\lib\Account_Service;
14 use DomainException;
15 use RuntimeException;
16
17 if ( ! defined( 'CYBOT_COOKIEBOT_VERSION' ) ) {
18 define( 'CYBOT_COOKIEBOT_VERSION', '1.0.0' );
19 }
20
21 class Cookiebot_WP {
22
23
24 public static function debug_log( $message ) {
25 if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
26 // phpcs:ignore
27 error_log( '[Cookiebot] ' . $message );
28 }
29 }
30
31 const COOKIEBOT_PLUGIN_VERSION = '4.5.0';
32 const COOKIEBOT_MIN_PHP_VERSION = '5.6.0';
33
34 /**
35 * @var Cookiebot_WP The single instance of the class
36 * @since 1.0.0
37 */
38 private static $instance = null;
39
40 private $account_service;
41
42 /**
43 * Main Cookiebot_WP Instance
44 *
45 * Ensures only one instance of Cookiebot_WP is loaded or can be loaded.
46 *
47 * @return Cookiebot_WP - Main instance
48 * @throws RuntimeException
49 * @version 1.0.0
50 * @since 1.0.0
51 * @static
52 */
53 public static function instance() {
54 if ( is_null( self::$instance ) ) {
55 self::$instance = new self();
56 }
57
58 return self::$instance;
59 }
60
61 /**
62 * Cookiebot_WP Constructor.
63 *
64 * @throws RuntimeException
65 * @since 1.0.0
66 * @access public
67 * @version 2.1.4
68 */
69 public function __construct() {
70 $this->throw_exception_if_php_version_is_incompatible();
71 $this->cookiebot_init();
72 register_activation_hook( __FILE__, array( new Cookiebot_Activated(), 'run' ) );
73 register_deactivation_hook( __FILE__, array( new Cookiebot_Deactivated(), 'run' ) );
74
75 // Initialize services
76 $this->account_service = new Account_Service();
77 }
78
79 /**
80 * @throws RuntimeException
81 */
82 private function throw_exception_if_php_version_is_incompatible() {
83 if ( version_compare( PHP_VERSION, self::COOKIEBOT_MIN_PHP_VERSION, '<' ) ) {
84 $message = sprintf(
85 // translators: The placeholder is for the COOKIEBOT_MIN_PHP_VERSION constant
86 __( 'The Cookiebot plugin requires PHP version %s or greater.', 'cookiebot' ),
87 self::COOKIEBOT_MIN_PHP_VERSION
88 );
89 throw new DomainException( $message );
90 }
91 }
92
93 public function cookiebot_init() {
94 Cookiebot_Addons::instance();
95 add_action( 'init', array( $this, 'cookiebot_load_textdomain' ) );
96
97 if ( is_admin() ) {
98 ( new Menu_Settings() )->add_menu();
99 if ( is_multisite() && is_plugin_active_for_network( 'cookiebot/cookiebot.php' ) ) {
100 ( new Network_Menu_Settings() )->add_menu();
101 }
102 ( new Dashboard_Widget_Cookiebot_Status() )->register_hooks();
103 ( new Cookiebot_Notices() )->register_hooks();
104 ( new Cookiebot_Review() )->register_hooks();
105 }
106
107 ( new Consent_API_Helper() )->register_hooks();
108 ( new Cookiebot_Javascript_Helper() )->register_hooks();
109 ( new Cookiebot_Embedding_Shortcode() )->register_hooks();
110 ( new Cookiebot_Automatic_Updates() )->register_hooks();
111 ( new Widgets() )->register_hooks();
112 ( new Cookiebot_Gutenberg_Declaration_Block() )->register_hooks();
113 ( new WP_Rocket_Helper() )->register_hooks();
114
115 $this->set_default_options();
116 ( new Cookiebot_Admin_Links() )->register_hooks();
117 }
118
119 /**
120 * Returns true if an user is logged in and has an edit_themes capability
121 *
122 * @return bool
123 *
124 * @since 3.3.1
125 * @version 3.4.1
126 */
127 public static function can_current_user_edit_theme() {
128 if ( is_user_logged_in() &&
129 (
130 current_user_can( 'edit_themes' ) ||
131 current_user_can( 'edit_pages' ) ||
132 current_user_can( 'edit_posts' )
133 )
134 ) {
135 return true;
136 }
137
138 return false;
139 }
140
141 /**
142 * Loads translations textdomain
143 *
144 * @return void
145 */
146 public function cookiebot_load_textdomain() {
147 load_textdomain(
148 'cookiebot',
149 CYBOT_COOKIEBOT_PLUGIN_DIR . 'langs/cookiebot-' . get_locale() . '.mo'
150 );
151 load_plugin_textdomain( 'cookiebot', false, dirname( plugin_basename( __FILE__ ) ) . '/langs' );
152 }
153
154 /**
155 * @return string
156 */
157 public static function get_cbid() {
158 $network_setting = (string) get_site_option( 'cookiebot-cbid', '' );
159 $setting = (string) get_option( 'cookiebot-cbid', $network_setting );
160
161 return empty( $setting ) ? $network_setting : $setting;
162 }
163
164 public static function get_auth_token() {
165 $token = (string) get_option( 'cookiebot-auth-token' );
166 return $token;
167 }
168
169 public static function get_user_data() {
170 $user_data = get_option( 'cookiebot-user-data', '' );
171 return empty( $user_data ) ? '' : $user_data;
172 }
173
174 /**
175 * Check if the user was onboarded via signup
176 *
177 * @return bool
178 */
179 public static function was_onboarded_via_signup() {
180 $user_data = self::get_user_data();
181 return ! empty( $user_data ) && isset( $user_data['onboarded_via_signup'] ) && $user_data['onboarded_via_signup'] === true;
182 }
183
184 public static function get_scan_status() {
185 $scan_status = get_option( 'cookiebot-scan-status', '' );
186 return empty( $scan_status ) ? '' : $scan_status;
187 }
188
189 /**
190 * @return string
191 */
192 public static function get_network_cbid() {
193 return get_site_option( 'cookiebot-cbid', '' );
194 }
195
196 /**
197 * @return string
198 */
199 public static function get_banner_enabled() {
200 $enabled = get_option( 'cookiebot-banner-enabled', 'default' );
201 if ( $enabled === 'default' ) {
202 $enabled = '1';
203 update_option( 'cookiebot-banner-enabled', $enabled );
204 }
205 return $enabled;
206 }
207
208 /**
209 * @return string
210 */
211 public static function get_gcm_enabled() {
212 $enabled = get_option( 'cookiebot-gcm', 'default' );
213 if ( $enabled === 'default' ) {
214 $enabled = '1';
215 update_option( 'cookiebot-gcm', $enabled );
216 }
217 return $enabled;
218 }
219
220 /**
221 * @return string
222 */
223 public static function get_preview_link() {
224 $url = get_site_option( 'siteurl', '#' );
225 return $url;
226 }
227
228 /**
229 * @return string
230 */
231 public static function get_subscription_type() {
232 $raw_data = get_option( 'cookiebot-user-data', '' );
233
234 if ( empty( $raw_data ) ) {
235 self::debug_log( 'Raw data is empty, returning Free' );
236 return 'Free';
237 }
238
239 // Use the data directly if it's already an array
240 $data = is_array( $raw_data ) ? $raw_data : json_decode( $raw_data, true );
241
242 // Check if we have the new subscription structure
243 if ( ! isset( $data['subscriptions']['active'] ) ) {
244 self::debug_log( 'No active subscription found, returning Free' );
245 return 'Free';
246 }
247
248 $subscription = $data['subscriptions']['active'];
249 $status = isset( $subscription['subscription_status'] ) ? $subscription['subscription_status'] : '';
250 $price_plan = isset( $subscription['price_plan'] ) ? $subscription['price_plan'] : 'free';
251
252 self::debug_log( 'Subscription details:' );
253 self::debug_log( 'Status: ' . $status );
254 self::debug_log( 'Price Plan: ' . $price_plan );
255
256 // Check for trial status first
257 if ( in_array( $status, array( 'trial_will_be_billed', 'trial_missing_payment' ), true ) ) {
258 self::debug_log( 'Trial status detected, returning Premium trial' );
259 return 'Premium trial';
260 }
261
262 // If not in trial, check active subscriptions
263 if ( in_array( $status, array( 'active_auto_renew', 'active_no_renew' ), true ) ) {
264 // Map extended plan names to their base names
265 $plan_mapping = array(
266 'FreeExtended' => 'Free',
267 'EssentialExtended' => 'Essential',
268 'PlusExtended' => 'Plus',
269 'ProExtended' => 'Pro',
270 'BusinessExtended' => 'Business',
271 );
272
273 $result = isset( $plan_mapping[ $price_plan ] ) ? $plan_mapping[ $price_plan ] : ucfirst( $price_plan );
274 self::debug_log( 'Active subscription, returning: ' . $result );
275 return $result;
276 }
277
278 self::debug_log( 'No conditions met, returning Free' );
279 return 'Free';
280 }
281
282 /**
283 * @return string
284 */
285 public static function get_legal_framwework() {
286 $configuration = get_option( 'cookiebot-configuration', array() );
287 return isset( $configuration['legal_framework_template'] ) ? strtoupper( $configuration['legal_framework_template'] ) : 'GDPR';
288 }
289
290 /**
291 * @return string
292 */
293 public static function get_cookie_blocking_mode() {
294 $allowed_modes = array( 'auto', 'manual' );
295 $network_setting = (string) get_site_option( 'cookiebot-cookie-blocking-mode', 'manual' );
296 $setting = $network_setting === 'manual' ?
297 (string) get_option( 'cookiebot-cookie-blocking-mode', $network_setting ) :
298 $network_setting;
299
300 return in_array( $setting, $allowed_modes, true ) ? $setting : 'manual';
301 }
302
303 /**
304 * @return bool
305 */
306 public static function check_network_auto_blocking_mode() {
307 $network_setting = (string) get_site_option( 'cookiebot-cookie-blocking-mode' );
308
309 return $network_setting === 'auto' ? true : false;
310 }
311
312 /**
313 * @return string
314 */
315 public static function get_cookie_categories_status() {
316 return self::get_cookie_blocking_mode() === 'auto' ? 'disabled' : '';
317 }
318
319 /**
320 * @return bool
321 */
322 public static function is_cookie_category_selected( $option, $category ) {
323 $categories = get_option( $option );
324 if ( ! $categories || ! is_array( $categories ) ) {
325 return false;
326 }
327
328 return in_array( $category, $categories, true );
329 }
330
331 /**
332 * Cookiebot_WP Check if Cookiebot is active in admin
333 *
334 * @version 4.2.8
335 * @since 3.1.0
336 */
337 public static function cookiebot_disabled_in_admin() {
338 if ( ( is_network_admin() && get_site_option( 'cookiebot-nooutput-admin', false ) ) ||
339 ( ! is_network_admin() && get_site_option( 'cookiebot-nooutput-admin', false ) ) ||
340 ( ! is_network_admin() && get_option( 'cookiebot-nooutput-admin', false ) ) ) {
341 return true;
342 }
343
344 return false;
345 }
346
347 /**
348 * Cookiebot_WP Set default options
349 *
350 * @version 4.2.5
351 * @since 4.2.5
352 */
353 private function set_default_options() {
354 $options = array(
355 'cookiebot-nooutput-admin' => '1',
356 'cookiebot-gcm' => '1',
357 );
358
359 foreach ( $options as $option => $default ) {
360 if ( get_option( $option ) === false && ! get_option( $option . self::OPTION_FIRST_RUN_SUFFIX ) ) {
361 update_option( $option, $default );
362 }
363
364 if ( ( get_option( $option ) || get_option( $option ) !== false ) && ! get_option( $option . self::OPTION_FIRST_RUN_SUFFIX ) ) {
365 update_option( $option . self::OPTION_FIRST_RUN_SUFFIX, '1' );
366 }
367 }
368
369 self::set_tcf_version();
370 }
371
372 private static function set_tcf_version() {
373 $iab_version = get_option( 'cookiebot-tcf-version' );
374 if ( empty( $iab_version ) || $iab_version === 'IAB' ) {
375 update_option( 'cookiebot-tcf-version', 'TCFv2.2' );
376 }
377 }
378
379 public function set_settings_action_link( $actions ) {
380 $cblinks = array(
381 '<a href="' . esc_url( add_query_arg( 'page', 'cookiebot', admin_url( 'admin.php' ) ) ) . '">' . esc_html__( 'Dashboard', 'cookiebot' ) . '</a>',
382 );
383 $actions = array_merge( $actions, $cblinks );
384 return $actions;
385 }
386
387 /**
388 * @return string
389 */
390 public static function get_manager_language() {
391 $locale = get_locale();
392 $supported_langs = array(
393 'de_DE' => 'de',
394 'da_DK' => 'da',
395 'fr_FR' => 'fr',
396 'it_IT' => 'it',
397 'es_ES' => 'es',
398 );
399
400 return array_key_exists( $locale, $supported_langs ) ? $supported_langs[ $locale ] : esc_html( 'en' );
401 }
402
403 const OPTION_FIRST_RUN_SUFFIX = '-first-run';
404
405 public function get_usercentrics_script() {
406 $final_script = '';
407
408 // Enqueue Usercentrics scripts
409 wp_enqueue_script(
410 'usercentrics-tcf-stub',
411 'https://web.cmp.usercentrics.eu/tcf/stub.js',
412 array(),
413 CYBOT_COOKIEBOT_VERSION,
414 true
415 );
416
417 wp_enqueue_script(
418 'usercentrics-autoblocker',
419 'https://web.cmp.usercentrics.eu/modules/autoblocker.js',
420 array(),
421 CYBOT_COOKIEBOT_VERSION,
422 true
423 );
424
425 wp_enqueue_script(
426 'usercentrics-cmp',
427 'https://web.cmp.usercentrics.eu/ui/loader.js',
428 array(),
429 CYBOT_COOKIEBOT_VERSION,
430 true
431 );
432
433 // Add data attributes to the CMP script
434 wp_script_add_data(
435 'usercentrics-cmp',
436 'data-usercentrics',
437 'Usercentrics Consent Management Platform'
438 );
439 wp_script_add_data(
440 'usercentrics-cmp',
441 'data-settings-id',
442 '%s'
443 );
444 wp_script_add_data(
445 'usercentrics-cmp',
446 'async',
447 true
448 );
449
450 return $final_script;
451 }
452
453 public function enqueue_scripts() {
454 wp_enqueue_script(
455 'cookiebot',
456 'https://consent.cookiebot.com/uc.js',
457 array(),
458 CYBOT_COOKIEBOT_VERSION,
459 true
460 );
461
462 wp_enqueue_script(
463 'cookiebot-helper',
464 plugins_url( 'js/cookiebot-helper.js', dirname( __FILE__ ) ),
465 array( 'jquery' ),
466 CYBOT_COOKIEBOT_VERSION,
467 true
468 );
469
470 wp_enqueue_script(
471 'cookiebot-admin',
472 plugins_url( 'js/cookiebot-admin.js', dirname( __FILE__ ) ),
473 array( 'jquery' ),
474 CYBOT_COOKIEBOT_VERSION,
475 true
476 );
477 }
478
479 /**
480 * Clone object and return it
481 *
482 * @return object
483 *
484 * @since 1.0.0
485 */
486 public function get_cloned_object() {
487 $temp = clone $this;
488 return $temp;
489 }
490
491 /**
492 * Get the banner script HTML
493 *
494 * @return string
495 *
496 * @phpcs:disable WordPress.WP.EnqueuedResources.NonEnqueuedScript
497 */
498 public static function get_banner_script() {
499 $cbid = self::get_cbid();
500 self::debug_log( '=== get_banner_script: Starting ===' );
501 self::debug_log( 'CBID: ' . $cbid );
502
503 // Basic validation checks
504 if ( empty( $cbid ) || defined( 'COOKIEBOT_DISABLE_ON_PAGE' ) ) {
505 self::debug_log( 'get_banner_script: Basic validation failed - CBID empty or disabled' );
506 return '';
507 }
508
509 // Banner enabled check
510 $banner_enabled = get_option( 'cookiebot-banner-enabled', '1' );
511 self::debug_log( 'Banner enabled setting: ' . $banner_enabled );
512 if ( $banner_enabled === '0' ) {
513 self::debug_log( 'get_banner_script: Banner disabled in settings' );
514 return '';
515 }
516
517 // User verification and trial checks
518 $user_data = get_option( 'cookiebot-user-data', array() );
519
520 if ( ! empty( $user_data ) ) {
521 // Check unverified user trial
522 if ( isset( $user_data['email_verification_status'] ) &&
523 $user_data['email_verification_status'] === 'unverified' &&
524 isset( $user_data['trial_start_date'] ) ) {
525 self::debug_log( 'Checking unverified user trial...' );
526 self::debug_log( 'Trial start date: ' . $user_data['trial_start_date'] );
527 $trial_start = \DateTime::createFromFormat( 'd-m-Y H:i:s', str_replace( ' T', ' ', $user_data['trial_start_date'] ) );
528 $trial_end = clone $trial_start;
529 $trial_end = $trial_end->modify( '+14 days' );
530 self::debug_log( 'Trial end date: ' . $trial_end->format( 'Y-m-d H:i:s' ) );
531 if ( $trial_start && new \DateTime() > $trial_end ) {
532 self::debug_log( 'get_banner_script: Unverified user trial expired' );
533 return '';
534 }
535 }
536
537 // Check trial status
538 if ( isset( $user_data['subscription_status'] ) &&
539 $user_data['subscription_status'] === 'in_trial_non_billable' &&
540 isset( $user_data['trial_end_date'] ) ) {
541 self::debug_log( 'Checking trial status...' );
542 self::debug_log( 'Trial end date: ' . $user_data['trial_end_date'] );
543 $trial_end = \DateTime::createFromFormat( 'd-m-Y H:i:s', str_replace( ' T', ' ', $user_data['trial_end_date'] ) );
544 if ( $trial_end && new \DateTime() > $trial_end ) {
545 self::debug_log( 'get_banner_script: Trial period ended' );
546 return '';
547 }
548 }
549 }
550
551 // Output conditions check
552 $is_multisite = is_multisite();
553 $network_nooutput = $is_multisite ? get_site_option( 'cookiebot-nooutput', false ) : false;
554 $site_nooutput = get_option( 'cookiebot-nooutput', false );
555 $can_edit_theme = self::can_current_user_edit_theme();
556 $output_logged_in = get_option( 'cookiebot-output-logged-in' );
557
558 self::debug_log( 'Output conditions:' );
559 self::debug_log( 'Is multisite: ' . ( $is_multisite ? 'yes' : 'no' ) );
560 self::debug_log( 'Network nooutput: ' . ( $network_nooutput ? 'yes' : 'no' ) );
561 self::debug_log( 'Site nooutput: ' . ( $site_nooutput ? 'yes' : 'no' ) );
562 self::debug_log( 'Can edit theme: ' . ( $can_edit_theme ? 'yes' : 'no' ) );
563 self::debug_log( 'Output logged in: ' . ( $output_logged_in ? 'yes' : 'no' ) );
564
565 if ( $is_multisite && $network_nooutput ||
566 $site_nooutput ||
567 ( $can_edit_theme && ! $output_logged_in ) ) {
568 self::debug_log( 'get_banner_script: Output conditions not met' );
569 return '';
570 }
571
572 self::debug_log( 'get_banner_script: Generating dynamic script' );
573
574 // Build the script HTML
575 $script_html = '';
576
577 // Add TCF stub if IAB is enabled
578 $iab_enabled = ! empty( get_option( 'cookiebot-iab' ) );
579 // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
580 self::debug_log( 'IAB enabled: ' . ( $iab_enabled ? 'yes' : 'no' ) );
581 if ( $iab_enabled ) {
582 // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript
583 $script_html .= sprintf(
584 '<script src="%s"></script>',
585 esc_url( 'https://web.cmp.usercentrics.eu/tcf/stub.js' )
586 );
587 }
588
589 // Add autoblocker if auto mode is enabled
590 $blocking_mode = self::get_cookie_blocking_mode();
591 // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
592 self::debug_log( 'Blocking mode: ' . $blocking_mode );
593 if ( $blocking_mode === 'auto' ) {
594 // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript
595 $script_html .= sprintf(
596 '<script src="%s"></script>',
597 esc_url( 'https://web.cmp.usercentrics.eu/modules/autoblocker.js' )
598 );
599 }
600
601 // Add main banner script
602 // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript
603 $script_html .= sprintf(
604 '<script id="usercentrics-cmp" data-settings-id="%s" data-usercentrics="%s" src="%s" async></script>',
605 esc_attr( $cbid ),
606 esc_attr( 'Usercentrics Consent Management Platform' ),
607 esc_url( 'https://web.cmp.usercentrics.eu/ui/loader.js' )
608 );
609
610 self::debug_log( 'Final script HTML: ' . $script_html );
611 return $script_html;
612 }
613 }
614