name. Used to name a banner on the settings screen and * in Health, and to recognise one that decides only in the browser (see * banner()); any banner that sets a consent type counts, named or not. * Only plugins on the API's own list of compatible plugins belong here: * naming one that does not call the API as a banner that decides in the * browser would reassure falsely (Real Cookie Banner is not on that list). * * @var array */ private const BANNERS = array( 'complianz-gdpr/complianz-gpdr.php' => 'Complianz', 'complianz-gdpr-premium/complianz-gpdr-premium.php' => 'Complianz', 'cookie-law-info/cookie-law-info.php' => 'CookieYes', 'cookiebot/cookiebot.php' => 'Cookiebot', 'iubenda-cookie-law-solution/iubenda_cookie_solution.php' => 'Iubenda', 'gdpr-cookie-compliance/moove-gdpr.php' => 'GDPR Cookie Compliance', ); /** * Settings store. * * @var Settings */ private Settings $settings; /** * Constructor. * * @param Settings $settings Settings store. */ public function __construct( Settings $settings ) { $this->settings = $settings; } /** * Whether a consent banner is set up: the WP Consent API is there and a * banner has set a consent type. */ public function banner_active(): bool { return '' !== $this->consent_type(); } /** * The banner, as the settings screen shows it: * - `wp-consent-api`: a banner has set a consent type; with the plugin's * name when it is one we know (empty otherwise); * - `browser`: the WP Consent API is there, no consent type is set on the * server, and a banner plugin we know is active. It decides in the * browser, so the server cannot see a visitor's choice; with its name; * - `none`: no banner. * * @return array{type: string, name: string} */ public function banner(): array { if ( $this->banner_active() ) { return array( 'type' => 'wp-consent-api', 'name' => $this->known_banner(), ); } $name = $this->consent_api_active() ? $this->known_banner() : ''; if ( '' !== $name ) { return array( 'type' => 'browser', 'name' => $name, ); } return array( 'type' => 'none', 'name' => '', ); } /** * Whether marketing is allowed for this visitor, as far as the server can * tell: * - `off`: consent is not asked for, so yes; * - a banner is set up: what it says about marketing for this visitor; * - no banner the server can ask (one that decides only in the browser * included): yes only for Advanced mode with everything granted, where * consent is not asked for either; in every other case it is unknown, * and unknown is no. */ public function marketing_allows(): bool { $mode = (string) $this->settings->get( 'consent_mode' ); if ( 'off' === $mode ) { return true; } if ( $this->banner_active() ) { return $this->has_consent( 'marketing' ); } return 'advanced' === $mode && 'all_granted' === (string) $this->settings->get( 'consent_region_default' ); } /** * Whether the consent settings need a banner before any pixel can load: * Basic mode always, Advanced mode unless every visitor starts granted. * Used by Health to recommend one. */ public function banner_needed(): bool { $mode = (string) $this->settings->get( 'consent_mode' ); if ( 'basic' === $mode ) { return true; } return 'advanced' === $mode && 'all_granted' !== (string) $this->settings->get( 'consent_region_default' ); } /** * The consent type a banner has set ('optin' or 'optout'), or '' when the * WP Consent API is missing or no banner has set one. */ protected function consent_type(): string { if ( ! function_exists( 'wp_get_consent_type' ) ) { return ''; } $type = wp_get_consent_type(); return is_string( $type ) ? $type : ''; } /** * Whether the WP Consent API is installed: its wp_has_consent() exists, the * same test the consent bridge and the settings screen's config use. */ protected function consent_api_active(): bool { return function_exists( 'wp_has_consent' ); } /** * The name of the first active banner plugin we know, or ''. */ private function known_banner(): string { foreach ( self::BANNERS as $file => $name ) { if ( $this->plugin_active( $file ) ) { return $name; } } return ''; } /** * What the WP Consent API says about a category for this visitor. * * @param string $category The consent category. */ protected function has_consent( string $category ): bool { return function_exists( 'wp_has_consent' ) && (bool) wp_has_consent( $category ); } /** * Whether a plugin is active. Loads the plugin functions outside wp-admin * (REST requests). * * @param string $file Main file relative to the plugins folder. */ protected function plugin_active( string $file ): bool { if ( ! function_exists( 'is_plugin_active' ) && file_exists( ABSPATH . 'wp-admin/includes/plugin.php' ) ) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; } return function_exists( 'is_plugin_active' ) && is_plugin_active( $file ); } }