Plugin Directory

Changeset 3392903


Ignore:
Timestamp:
11/10/2025 11:30:24 AM (5 weeks ago)
Author:
RogierLankhorst
Message:

prepare for 2.0

Location:
wp-consent-api/trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • wp-consent-api/trunk/assets/css/wp-consent-api.css

    r2397444 r3392903  
    1 
    2 #health-check-accordion-block-wp-consent-api .title{
     1#health-check-accordion-block-wp-consent-api .title {
    32    pointer-events: none;
    43    font-weight: 600;
     
    65    padding-top: 10px;
    76}
    8 #health-check-accordion-block-wp-consent-api .actions{
     7
     8#health-check-accordion-block-wp-consent-api .actions {
    99    padding: 20px 0px;
    1010}
    11 #health-check-accordion-block-wp-consent-api p{
    1211
     12#health-check-accordion-block-wp-consent-api p {
    1313    background: #fff;
    1414    border-left: 4px solid #fff;
    15     box-shadow: 0 1px 1px 0 rgba(0,0,0,.1);
     15    box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.1);
    1616    margin: 5px 15px 2px;
    1717    padding: 1px 12px;
    1818    border-left-color: #ffb900;
    1919    margin: 5px 20px 15px 0px;
    20 
    2120}
  • wp-consent-api/trunk/assets/js/wp-consent-api.js

    r2540021 r3392903  
    66 *
    77 * Edit: chronologically it seems difficult to create a sort of filter for the consent type.
    8  * Let's change it so cookiebanners are just required to set it, it it's not available, we use a default, as defined here.
     8 * Let's change it so cookiebanners are just required to set it, if it's not available, we use a default, as defined here.
    99 *
    1010 * This way, if a consent management plugin does not define a consenttype, the one passed here will be used, and it will still work.
     
    1717
    1818/**
     19 * Check if a specific service has consent
     20 * @param {string} service
     21 */
     22function wp_has_service_consent(service) {
     23    //Check if it's in the consented services cookie
     24    let consented_services_json = consent_api_get_cookie(consent_api.cookie_prefix + '_' + 'consented_services');
     25    let consented_services;
     26    try {
     27        consented_services = JSON.parse(consented_services_json);
     28    } catch (e) {
     29        consented_services = {};
     30    }
     31
     32    if ( !consented_services.hasOwnProperty( service ) ){
     33        //default to the category
     34        const category = wp_get_service_category(service);
     35        return wp_has_consent( category );
     36    } else {
     37        return consented_services[service];
     38    }
     39}
     40/**
     41 * Check if a specific service is denied
     42 * @param {string} service
     43 */
     44function wp_is_service_denied( service ) {
     45    //Check if it's in the consented services cookie
     46    let consented_services_json = consent_api_get_cookie(consent_api.cookie_prefix + '_' + 'consented_services');
     47    let consented_services;
     48    try {
     49        consented_services = JSON.parse(consented_services_json);
     50    } catch (e) {
     51        consented_services = {};
     52    }
     53
     54    if ( !consented_services.hasOwnProperty( service ) ){
     55        return false;
     56    } else {
     57        return !consented_services[service];
     58    }
     59}
     60
     61/**
     62 * Set consent for a specific service
     63 * @param {string} service
     64 * @param {boolean} consented
     65 */
     66function wp_set_service_consent( service, consented ){
     67    let consented_services_json = consent_api_get_cookie(consent_api.cookie_prefix + '_' + 'consented_services');
     68    let consented_services;
     69    try {
     70        consented_services = JSON.parse(consented_services_json);
     71    } catch (e) {
     72        consented_services = {};
     73    }
     74    consented_services[service] = consented;
     75    consent_api_set_cookie(consent_api.cookie_prefix + '_consented_services', JSON.stringify(consented_services));
     76
     77    let details = {};
     78    details.service = service;
     79    details.value = consented;
     80    let event = new CustomEvent('wp_consent_api_status_change_service', { detail: details });
     81    document.dispatchEvent(event);
     82}
     83
     84
     85/**
    1986 * Check if a user has given consent for a specific category.
    2087 *
    21  * @param {string} category The category to check consent against.
     88 * @param {string} category The item to check consent against.
    2289 */
    2390function wp_has_consent(category) {
    24     var consent_type;
    25     if (typeof (window.wp_consent_type) !== "undefined"){
     91    let has_consent = false;
     92    let consent_type;
     93    if ( typeof (window.wp_consent_type) !== "undefined" ){
    2694        consent_type = window.wp_consent_type;
    2795    }  else {
     
    2997    }
    3098
    31     var has_consent_level = false;
    32     var cookie_value = consent_api_get_cookie(consent_api.cookie_prefix + '_' + category);
    33 
    34     if (!consent_type) {
     99    let cookie_value = consent_api_get_cookie(consent_api.cookie_prefix + '_' + category);
     100    if ( !consent_type ) {
    35101        //if consent_type is not set, there's no consent management, we should return true to activate all cookies
    36         has_consent_level = true;
    37 
     102        has_consent = true;
    38103    } else if (consent_type.indexOf('optout') !== -1 && cookie_value === '') {
    39104        //if it's opt out and no cookie is set we should also return true
    40         has_consent_level = true;
    41 
     105        has_consent = true;
    42106    } else {
    43107        //all other situations, return only true if value is allow
    44         has_consent_level = (cookie_value === 'allow');
     108        has_consent = (cookie_value === 'allow');
    45109    }
    46110
    47     return has_consent_level;
     111    return has_consent;
     112}
     113
     114/**
     115 * Retrieve the category of a registered service
     116 *
     117 * @param {string} service
     118 * @returns {string}
     119 */
     120function wp_get_service_category( service ) {
     121    // Check if services array exists and is valid
     122    if (!consent_api.services || !Array.isArray(consent_api.services)) {
     123        return 'marketing';
     124    }
     125
     126    let services = consent_api.services;
     127    for (let i = 0; i < services.length; i++) {
     128        if (services[i] &&
     129            services[i].name === service &&
     130            services[i].category) {
     131            return services[i].category;
     132        }
     133    }
     134    return 'marketing';
    48135}
    49136
     
    55142 */
    56143function consent_api_set_cookie(name, value) {
    57     var secure = ";secure";
    58     var days = consent_api.cookie_expiration;
    59     var date = new Date();
     144    let secure = ";secure";
     145    let days = consent_api.cookie_expiration;
     146    let date = new Date();
    60147    date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
    61     var expires = ";expires=" + date.toGMTString();
     148    let expires = ";expires=" + date.toGMTString();
    62149
    63150    if (window.location.protocol !== "https:") secure = '';
     
    77164    for (var i = 0; i < cookies.length; i++) {
    78165        var cookie = cookies[i].trim();
    79         if (cookie.indexOf(name) == 0)
     166        if ( cookie.indexOf(name) === 0 )
    80167            return cookie.substring(name.length, cookie.length);
    81168    }
     
    92179 */
    93180function wp_set_consent(category, value) {
    94     var event;
    95     if (value !== 'allow' && value !== 'deny') return;
     181    let event;
     182    if (value !== 'allow' && value !== 'deny') return;
    96183    var previous_value = consent_api_get_cookie(consent_api.cookie_prefix + '_' + category);
    97     consent_api_set_cookie(consent_api.cookie_prefix + '_' + category, value);
    98 
    99     //do not trigger a change event if nothing has changed.
    100     if ( previous_value === value ) return;
    101 
    102     var changedConsentCategory = [];
    103     changedConsentCategory[category] = value;
    104     try {
    105         // For modern browsers except IE:
    106         event = new CustomEvent('wp_listen_for_consent_change', {detail: changedConsentCategory});
    107     } catch (err) {
    108         // If IE 11 (or 10 or 9...?)
    109         event = document.createEvent('Event');
    110         event.initEvent('wp_listen_for_consent_change', true, true);
    111         event.detail = changedConsentCategory;
    112     }
    113     // Dispatch/Trigger/Fire the event
    114     document.dispatchEvent(event);
    115 }
    116 
    117 
    118 
    119 
    120 
    121 
    122 
    123 
     184    consent_api_set_cookie(consent_api.cookie_prefix + '_' + category, value);
     185
     186    //do not trigger a change event if nothing has changed.
     187    if ( previous_value === value ) return;
     188
     189    var changedConsentCategory = [];
     190    changedConsentCategory[category] = value;
     191    try {
     192        // For modern browsers except IE:
     193        event = new CustomEvent('wp_listen_for_consent_change', {detail: changedConsentCategory});
     194    } catch (err) {
     195        // If IE 11 (or 10 or 9...?)
     196        event = document.createEvent('Event');
     197        event.initEvent('wp_listen_for_consent_change', true, true);
     198        event.detail = changedConsentCategory;
     199    }
     200    // Dispatch/Trigger/Fire the event
     201    document.dispatchEvent(event);
     202}
     203
     204
     205
  • wp-consent-api/trunk/assets/js/wp-consent-api.min.js

    r2540021 r3392903  
    1 "use strict";window.wp_fallback_consent_type=consent_api.consent_type;window.waitfor_consent_hook=consent_api.waitfor_consent_hook;function wp_has_consent(category){var consent_type;if(typeof window.wp_consent_type!=="undefined"){consent_type=window.wp_consent_type}else{consent_type=window.wp_fallback_consent_type}var has_consent_level=false;var cookie_value=consent_api_get_cookie(consent_api.cookie_prefix+"_"+category);if(!consent_type){has_consent_level=true}else if(consent_type.indexOf("optout")!==-1&&cookie_value===""){has_consent_level=true}else{has_consent_level=cookie_value==="allow"}return has_consent_level}function consent_api_set_cookie(name,value){var secure=";secure";var days=consent_api.cookie_expiration;var date=new Date;date.setTime(date.getTime()+days*24*60*60*1e3);var expires=";expires="+date.toGMTString();if(window.location.protocol!=="https:")secure="";document.cookie=name+"="+value+secure+expires+";path=/"}function consent_api_get_cookie(name){name=name+"=";var cookies=window.document.cookie.split(";");for(var i=0;i<cookies.length;i++){var cookie=cookies[i].trim();if(cookie.indexOf(name)==0)return cookie.substring(name.length,cookie.length)}return""}function wp_set_consent(category,value){var event;if(value!=="allow"&&value!=="deny")return;var previous_value=consent_api_get_cookie(consent_api.cookie_prefix+"_"+category);consent_api_set_cookie(consent_api.cookie_prefix+"_"+category,value);if(previous_value===value)return;var changedConsentCategory=[];changedConsentCategory[category]=value;try{event=new CustomEvent("wp_listen_for_consent_change",{detail:changedConsentCategory})}catch(err){event=document.createEvent("Event");event.initEvent("wp_listen_for_consent_change",true,true);event.detail=changedConsentCategory}document.dispatchEvent(event)}
     1"use strict";function wp_has_service_consent(e){var n=consent_api_get_cookie(consent_api.cookie_prefix+"_consented_services");let t;try{t=JSON.parse(n)}catch(e){t={}}return t.hasOwnProperty(e)?t[e]:wp_has_consent(wp_get_service_category(e))}function wp_is_service_denied(e){var n=consent_api_get_cookie(consent_api.cookie_prefix+"_consented_services");let t;try{t=JSON.parse(n)}catch(e){t={}}return!!t.hasOwnProperty(e)&&!t[e]}function wp_set_service_consent(e,n){var t=consent_api_get_cookie(consent_api.cookie_prefix+"_consented_services");let o;try{o=JSON.parse(t)}catch(e){o={}}o[e]=n,consent_api_set_cookie(consent_api.cookie_prefix+"_consented_services",JSON.stringify(o));t={},t.service=e,t.value=n,e=new CustomEvent("wp_consent_api_status_change_service",{detail:t});document.dispatchEvent(e)}function wp_has_consent(e){let n=!1,t;t=void 0!==window.wp_consent_type?window.wp_consent_type:window.wp_fallback_consent_type;e=consent_api_get_cookie(consent_api.cookie_prefix+"_"+e);return n=!t||-1!==t.indexOf("optout")&&""===e||"allow"===e}function wp_get_service_category(n){if(consent_api.services&&Array.isArray(consent_api.services)){var t=consent_api.services;for(let e=0;e<t.length;e++)if(t[e]&&t[e].name===n&&t[e].category)return t[e].category}return"marketing"}function consent_api_set_cookie(e,n){let t=";secure";var o=consent_api.cookie_expiration,i=new Date,o=(i.setTime(i.getTime()+24*o*60*60*1e3),";expires="+i.toGMTString());"https:"!==window.location.protocol&&(t=""),document.cookie=e+"="+n+t+o+";path=/"}function consent_api_get_cookie(e){e+="=";for(var n=window.document.cookie.split(";"),t=0;t<n.length;t++){var o=n[t].trim();if(0===o.indexOf(e))return o.substring(e.length,o.length)}return""}function wp_set_consent(e,n){let t;if("allow"===n||"deny"===n){var o=consent_api_get_cookie(consent_api.cookie_prefix+"_"+e);if(consent_api_set_cookie(consent_api.cookie_prefix+"_"+e,n),o!==n){o=[];o[e]=n;try{t=new CustomEvent("wp_listen_for_consent_change",{detail:o})}catch(e){(t=document.createEvent("Event")).initEvent("wp_listen_for_consent_change",!0,!0),t.detail=o}document.dispatchEvent(t)}}}window.wp_fallback_consent_type=consent_api.consent_type,window.waitfor_consent_hook=consent_api.waitfor_consent_hook;
  • wp-consent-api/trunk/readme.md

    r3201472 r3392903  
    99**License**: GPL2
    1010
    11 **Tested up to**: 5.3
    12 
    13 **Requires PHP**: 5.6
     11**Tested up to**: 6.8
     12
     13**Requires PHP**: 7.4
    1414
    1515**Stable tag**: 1.0.0
  • wp-consent-api/trunk/readme.txt

    r3373533 r3392903  
    66License URI: http://www.gnu.org/licenses/gpl-2.0.html
    77Tested up to: 6.8
    8 Requires PHP: 7.2
     8Requires PHP: 7.4
    99Stable tag: 1.0.8
    1010
     
    5252
    5353Categories and most other stuff can be extended with a filter.
     54
     55= Service-level consent =
     56In addition to category-based consent, the API supports service-level consent control. This allows consent management plugins to grant or deny consent for specific services (like 'google-analytics' or 'facebook-pixel') independently from their category. When checking service consent with wp_has_service_consent(), the API first checks if explicit consent exists for that service. If no explicit consent is set, it falls back to the consent status of the service's category. This enables fine-grained control: a user might accept statistics cookies in general, but explicitly deny a specific analytics service.
     57
     58Service consent can be checked and set both server-side (PHP) and client-side (JavaScript):
     59
     60PHP:
     61`
     62//check if a specific service has consent
     63if ( wp_has_service_consent( 'google-analytics' ) ) {
     64    //activate google analytics
     65}
     66
     67//check if a service is explicitly denied
     68if ( wp_is_service_denied( 'facebook-pixel' ) ) {
     69    //service was explicitly denied by user
     70}
     71
     72//set service consent
     73wp_set_service_consent( 'google-analytics', true ); //grant consent
     74wp_set_service_consent( 'facebook-pixel', false ); //deny consent
     75
     76//listen for service consent changes
     77add_action( 'wp_consent_service_changed', function( $service, $consented ) {
     78    error_log( "Service {$service} consent changed to: " . ( $consented ? 'granted' : 'denied' ) );
     79}, 10, 2 );
     80`
     81
     82JavaScript:
     83`
     84//check service consent
     85if ( wp_has_service_consent( 'youtube' ) ) {
     86    //activate tracking
     87}
     88
     89//check if explicitly denied
     90if ( wp_is_service_denied( 'facebook-pixel' ) ) {
     91    //service denied
     92}
     93
     94//set service consent
     95wp_set_service_consent( 'youtube', true );
     96
     97//listen for service consent changes
     98document.addEventListener( 'wp_consent_api_status_change_service', function( e ) {
     99    console.log( 'Service: ' + e.detail.service + ', consented: ' + e.detail.value );
     100});
    54101
    55102## Existing integrations
     
    103150document.dispatchEvent( event );
    104151
     152//dispatch event when consent type is defined
     153let event = new CustomEvent('wp_consent_type_defined');
     154document.dispatchEvent( event );
     155
    105156//consent management plugin sets cookie when consent category value changes
    106157wp_set_consent('marketing', 'allow');
     
    151202}
    152203`
    153 Any code suggestions? We're on [GitHub](https://github.com/rlankhorst/wp-consent-level-api) as well!
     204Any code suggestions? We're on [GitHub](https://github.com/WordPress/wp-consent-level-api) as well!
    154205
    155206== Installation ==
     
    191242
    192243== Changelog ==
     244= 2.0.0 =
     245* New: Service-level consent API - allows granular consent control per service in addition to category-based consent
     246* New: `wp_has_service_consent()` function to check if a specific service has consent
     247* New: `wp_is_service_denied()` function to check if a specific service is explicitly denied
     248* New: `wp_set_service_consent()` function to set consent for a specific service
     249* New: `wp_consent_service_changed` action hook fires when service consent changes
     250* New: JavaScript functions `wp_has_service_consent()`, `wp_is_service_denied()`, and `wp_set_service_consent()`
     251* New: JavaScript event `wp_consent_api_status_change_service` for service consent changes
     252* Improvement: Added type hints throughout codebase for better code quality and IDE support
     253* Improvement: Added `init()` method for cleaner plugin initialization
     254
    193255= 1.0.8 =
    194256* Updated tested up to
    195257* Dropped loading of translations, and loading of plugin_data, to prevent translation loading notices by WordPress 6.7, props @mujuonly
    196258* Dropped obsolete function wp_has_cookie_info, props @szepeviktor
    197 
    198 = 1.0.7 =
    199 * Tested up to
    200259
    201260= 1.0.7 =
  • wp-consent-api/trunk/wp-consent-api.php

    r3235822 r3392903  
    22/**
    33 * This file is part of WP Consent API.
    4  *
    5  * Copyright 2020 Rogier Lankhorst and the WordPress Core Privacy team.
    64 *
    75 * This program is free software: you can redistribute it and/or modify
     
    2523 * Plugin URI:        https://wordpress.org/plugins/wp-consent-api
    2624 * Description:       Consent Level API to read and register the current consent level for cookie management and improving compliance with privacy laws.
    27  * Version:           1.0.8
    28  * Author:            wordpressdotorg
    29  * Author URI:        https://github.com/rlankhorst/wp-consent-level-api
     25 * Version:           2.0.0
     26 * Author:            WordPress Contributors
     27 * Author URI:        https://github.com/WordPress/wp-consent-level-api
    3028 * Requires at least: 5.0
    31  * Requires PHP:      5.6
     29 * Requires PHP:      7.4
    3230 * License:           GPL2+
    3331 * License URI:       http://www.gnu.org/licenses/gpl-2.0.html
     
    3937}
    4038
    41 
    42 if ( ! function_exists( 'wp_consent_api_activation_check' ) ) {
     39if ( ! class_exists( 'WP_Consent_API' ) ) {
    4340    /**
    44      * Checks if the plugin can safely be activated, at least php 5.6 and wp 5.0
    45      *
    46      * @since 1.0.0
     41     * WP_Consent_API class.
    4742     */
    48     function wp_consent_api_activation_check() {
    49         global $wp_version;
    50 
    51         if ( version_compare( PHP_VERSION, '5.6', '<' ) ) {
    52             deactivate_plugins( plugin_basename( __FILE__ ) );
    53             wp_die( esc_html( __( 'This plugin requires PHP 5.6 or higher', 'wp-consent-api' ) ) );
    54         }
    55 
    56         if ( version_compare( $wp_version, '5.0', '<' ) ) {
    57             deactivate_plugins( plugin_basename( __FILE__ ) );
    58             wp_die( esc_html( __( 'This plugin requires WordPress 5.0 or higher', 'wp-consent-api' ) ) );
    59         }
    60     }
    61 }
    62 register_activation_hook( __FILE__, 'wp_consent_api_activation_check' );
    63 
    64 if ( ! class_exists( 'WP_CONSENT_API' ) ) {
    65     /**
    66      * WP_CONSENT_API class.
    67      */
    68     class WP_CONSENT_API {
     43    class WP_Consent_API {
    6944        /**
    7045         * Instance.
     
    7247         * @since 1.0.0
    7348         *
    74          * @var WP_CONSENT_API|null
     49         * @var WP_Consent_API|null
    7550         */
    7651        private static $instance;
     
    7954         * Config.
    8055         *
    81          * @var WP_CONSENT_API_CONFIG
     56         * @var WP_Consent_API_Config
    8257         */
    8358        public static $config;
     
    8762         * Site Health Checks.
    8863         *
    89          * @var WP_CONSENT_API_SITE_HEALTH
     64         * @var WP_Consent_API_Site_Health
    9065         */
    9166        public static $site_health;
     
    9469         * Cookie info
    9570         *
    96          * @var WP_CONSENT_API_COOKIE_INFO
     71         * @var WP_Consent_API_Cookie_Info
    9772         */
    9873        public static $cookie_info;
     
    10378         * @since 1.0.0
    10479         *
    105          * @return WP_CONSENT_API
     80         * @return WP_Consent_API
    10681         */
    10782        public static function get_instance() {
     
    11085            }
    11186            return self::$instance;
     87        }
     88
     89        /**
     90         * Initialize the plugin.
     91         *
     92         * @since 1.0.0
     93         *
     94         * @return void
     95         */
     96        public static function init(): void {
     97            self::get_instance();
    11298        }
    11399
     
    123109            $this->includes();
    124110
    125             self::$config      = new WP_CONSENT_API_CONFIG();
    126             self::$site_health = new WP_CONSENT_API_SITE_HEALTH();
    127             self::$cookie_info = new WP_CONSENT_API_COOKIE_INFO();
     111            self::$config      = new WP_Consent_API_Config();
     112            self::$site_health = new WP_Consent_API_Site_Health();
     113            self::$cookie_info = new WP_Consent_API_Cookie_Info();
    128114        }
    129115
     
    139125            define( 'WP_CONSENT_API_PATH', plugin_dir_path( __FILE__ ) );
    140126            define( 'WP_CONSENT_API_PLUGIN', plugin_basename( __FILE__ ) );
    141             define( 'WP_CONSENT_API_VERSION', '1.0.8' );
     127            define( 'WP_CONSENT_API_VERSION', '2.0.0' );
    142128            define( 'WP_CONSENT_API_PLUGIN_FILE', __FILE__ );
    143129        }
     
    151137         */
    152138        private function includes() {
    153             require_once WP_CONSENT_API_PATH . 'config.php';
    154             require_once WP_CONSENT_API_PATH . 'cookie-info.php';
    155             require_once WP_CONSENT_API_PATH . 'api.php';
    156             require_once WP_CONSENT_API_PATH . 'site-health.php';
    157             require_once WP_CONSENT_API_PATH . 'wordpress-comments.php';
     139            require_once WP_CONSENT_API_PATH . 'inc/class-wp-consent-api-config.php';
     140            require_once WP_CONSENT_API_PATH . 'inc/class-wp-consent-api-cookie-info.php';
     141            require_once WP_CONSENT_API_PATH . 'inc/class-wp-consent-api-site-health.php';
     142            require_once WP_CONSENT_API_PATH . 'inc/api-functions.php';
     143            require_once WP_CONSENT_API_PATH . 'inc/wordpress-comments-functions.php';
    158144        }
    159145    }
     
    162148     * Load the plugins main class.
    163149     */
    164     add_action( 'plugins_loaded', array( WP_CONSENT_API::class, 'get_instance' ), 9 );
     150    add_action( 'plugins_loaded', array( WP_Consent_API::class, 'init' ), 9 );
    165151}
Note: See TracChangeset for help on using the changeset viewer.