diff --git a/.eslintrc.js b/.eslintrc.js index 5ff0d04..0faf417 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -23,7 +23,7 @@ module.exports = { pressidiumCCClientDetails: 'readonly', pressidiumCCFeedbackDetails: 'readonly', pressidiumCookiesBlockData: 'readonly', - initCookieConsent: true, + CookieConsent: true, }, rules: { 'react/react-in-jsx-scope': 'off', diff --git a/README.md b/README.md index 72810db..0f214ba 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ * [Setup](#setup) * [Features](#features) * [Credits](#credits) +* [Contributing](#contributing) * [License](#license) * [About Pressidium](#about-pressidium) @@ -51,7 +52,7 @@ ![Color picker screenshot](./.wordpress-org/screenshot-2.png) -Easily modify the cookie consent banner and settings modal text. Pick one of the built-in color presets to match your website’s aesthetic, or adjust the color of individual components via our convenient color picker. Choose from a variety of layouts, positions, and transitions directly from the WordPress dashboard. +Easily modify the cookie consent banner and preferences modal text. Pick one of the built-in color presets to match your website’s aesthetic, or adjust the color of individual components via our convenient color picker. Choose from a variety of layouts, positions, and transitions directly from the WordPress dashboard. ### 🪶 Lightweight @@ -65,11 +66,11 @@ An a11y friendly plugin — fully accessible and WAI-ARIA compliant. ![Translations tab screenshot](./.wordpress-org/screenshot-4.png) -Modify any text in the cookie consent banner and settings modal, and provide translations. Choose the language auto-detection strategy you prefer — either read the user’s browser language or read the markup of the current page to identify its primary language. +Modify any text in the cookie consent banner and preferences modal, and provide translations. Choose the language auto-detection strategy you prefer — either read the user’s browser language or read the markup of the current page to identify its primary language. ### 📱 Responsive -Fully responsive and mobile-friendly cookie consent banner and settings modal. +Fully responsive and mobile-friendly cookie consent banner and preferences modal. ### 🙅 Block scripts @@ -127,7 +128,7 @@ Add the **Pressidium Cookies Table** block for the Block Editor to display a dyn ### ⌨️ Control it programmatically -Programmatically control the plugin. Conditionally show/hide the cookie consent banner and/or the settings modal, accept one (or more) cookie categories, erase cookies, load previously blocked scripts, etc. +Programmatically control the plugin. Conditionally show/hide the cookie consent banner and/or the preferences modal, accept one (or more) cookie categories, erase cookies, load previously blocked scripts, etc. ## Credits diff --git a/assets/css/admin-styles.css b/assets/css/admin-styles.css new file mode 100644 index 0000000..bf68a1e --- /dev/null +++ b/assets/css/admin-styles.css @@ -0,0 +1,18 @@ +.plugins .plugin-title .pressidium-action-link { + white-space: nowrap; +} + +.plugins .plugin-title .pressidium-action-link .dashicons { + float: none; + padding: 0; + width: inherit; + height: inherit; +} + +.plugins .plugin-title .pressidium-action-link .dashicons::before { + padding: inherit; + background-color: inherit; + box-shadow: none; + font-size: inherit; + color: inherit; +} diff --git a/assets/images/performance-banner.png b/assets/images/performance-banner.png new file mode 100644 index 0000000..c75a96f Binary files /dev/null and b/assets/images/performance-banner.png differ diff --git a/composer.json b/composer.json index 5b28786..f9a97ac 100644 --- a/composer.json +++ b/composer.json @@ -36,6 +36,7 @@ "phpstan/extension-installer": "^1.4", "coenjacobs/mozart": "^0.7.1", "league/container": "^3.4", + "psr/simple-cache": "^1.0", "ext-json": "*", "psr/log": "^1.1", "phpcsstandards/phpcsutils": "^1.0", @@ -61,6 +62,7 @@ "packages": [ "league/container", "psr/log", + "psr/simple-cache", "nyholm/psr7", "guzzlehttp/guzzle", "orhanerday/open-ai", diff --git a/composer.lock b/composer.lock index f758690..56d4da4 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "82a98fe846cbada84d31b78c14e9576d", + "content-hash": "f6dc0764405b9c4cdc315c0ea86f3827", "packages": [], "packages-dev": [ { @@ -444,16 +444,16 @@ }, { "name": "dealerdirect/phpcodesniffer-composer-installer", - "version": "v1.2.0", + "version": "v1.2.1", "source": { "type": "git", "url": "https://github.com/PHPCSStandards/composer-installer.git", - "reference": "845eb62303d2ca9b289ef216356568ccc075ffd1" + "reference": "963f0c67bffde0eac41b56be71ac0e8ba132f0bd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/composer-installer/zipball/845eb62303d2ca9b289ef216356568ccc075ffd1", - "reference": "845eb62303d2ca9b289ef216356568ccc075ffd1", + "url": "https://api.github.com/repos/PHPCSStandards/composer-installer/zipball/963f0c67bffde0eac41b56be71ac0e8ba132f0bd", + "reference": "963f0c67bffde0eac41b56be71ac0e8ba132f0bd", "shasum": "" }, "require": { @@ -536,7 +536,7 @@ "type": "thanks_dev" } ], - "time": "2025-11-11T04:32:07+00:00" + "time": "2026-05-06T08:26:05+00:00" }, { "name": "dnoegel/php-xdg-base-dir", @@ -577,29 +577,29 @@ }, { "name": "doctrine/deprecations", - "version": "1.1.5", + "version": "1.1.6", "source": { "type": "git", "url": "https://github.com/doctrine/deprecations.git", - "reference": "459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38" + "reference": "d4fe3e6fd9bb9e72557a19674f44d8ac7db4c6ca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/deprecations/zipball/459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38", - "reference": "459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/d4fe3e6fd9bb9e72557a19674f44d8ac7db4c6ca", + "reference": "d4fe3e6fd9bb9e72557a19674f44d8ac7db4c6ca", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, "conflict": { - "phpunit/phpunit": "<=7.5 || >=13" + "phpunit/phpunit": "<=7.5 || >=14" }, "require-dev": { - "doctrine/coding-standard": "^9 || ^12 || ^13", - "phpstan/phpstan": "1.4.10 || 2.1.11", + "doctrine/coding-standard": "^9 || ^12 || ^14", + "phpstan/phpstan": "1.4.10 || 2.1.30", "phpstan/phpstan-phpunit": "^1.0 || ^2", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6 || ^10.5 || ^11.5 || ^12", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6 || ^10.5 || ^11.5 || ^12.4 || ^13.0", "psr/log": "^1 || ^2 || ^3" }, "suggest": { @@ -619,9 +619,9 @@ "homepage": "https://www.doctrine-project.org/", "support": { "issues": "https://github.com/doctrine/deprecations/issues", - "source": "https://github.com/doctrine/deprecations/tree/1.1.5" + "source": "https://github.com/doctrine/deprecations/tree/1.1.6" }, - "time": "2025-04-07T20:06:18+00:00" + "time": "2026-02-07T07:09:04+00:00" }, { "name": "felixfbecker/advanced-json-rpc", @@ -1063,16 +1063,16 @@ }, { "name": "guzzlehttp/psr7", - "version": "2.8.0", + "version": "2.9.0", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "21dc724a0583619cd1652f673303492272778051" + "reference": "7d0ed42f28e42d61352a7a79de682e5e67fec884" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/21dc724a0583619cd1652f673303492272778051", - "reference": "21dc724a0583619cd1652f673303492272778051", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/7d0ed42f28e42d61352a7a79de682e5e67fec884", + "reference": "7d0ed42f28e42d61352a7a79de682e5e67fec884", "shasum": "" }, "require": { @@ -1088,6 +1088,7 @@ "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", "http-interop/http-factory-tests": "0.9.0", + "jshttp/mime-db": "1.54.0.1", "phpunit/phpunit": "^8.5.44 || ^9.6.25" }, "suggest": { @@ -1159,7 +1160,7 @@ ], "support": { "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/2.8.0" + "source": "https://github.com/guzzle/psr7/tree/2.9.0" }, "funding": [ { @@ -1175,7 +1176,7 @@ "type": "tidelift" } ], - "time": "2025-08-23T21:21:41+00:00" + "time": "2026-03-10T16:41:02+00:00" }, { "name": "league/container", @@ -1459,16 +1460,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.19.4", + "version": "v4.19.5", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "715f4d25e225bc47b293a8b997fe6ce99bf987d2" + "reference": "51bd93cc741b7fc3d63d20b6bdcd99fdaa359837" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/715f4d25e225bc47b293a8b997fe6ce99bf987d2", - "reference": "715f4d25e225bc47b293a8b997fe6ce99bf987d2", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/51bd93cc741b7fc3d63d20b6bdcd99fdaa359837", + "reference": "51bd93cc741b7fc3d63d20b6bdcd99fdaa359837", "shasum": "" }, "require": { @@ -1483,11 +1484,6 @@ "bin/php-parse" ], "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.9-dev" - } - }, "autoload": { "psr-4": { "PhpParser\\": "lib/PhpParser" @@ -1509,9 +1505,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.19.4" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.19.5" }, - "time": "2024-09-29T15:01:53+00:00" + "time": "2025-12-06T11:45:25+00:00" }, { "name": "nyholm/psr7", @@ -1794,16 +1790,16 @@ }, { "name": "php-stubs/wordpress-stubs", - "version": "v6.8.3", + "version": "v6.9.1", "source": { "type": "git", "url": "https://github.com/php-stubs/wordpress-stubs.git", - "reference": "abeb5a8b58fda7ac21f15ee596f302f2959a7114" + "reference": "f12220f303e0d7c0844c0e5e957b0c3cee48d2f7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-stubs/wordpress-stubs/zipball/abeb5a8b58fda7ac21f15ee596f302f2959a7114", - "reference": "abeb5a8b58fda7ac21f15ee596f302f2959a7114", + "url": "https://api.github.com/repos/php-stubs/wordpress-stubs/zipball/f12220f303e0d7c0844c0e5e957b0c3cee48d2f7", + "reference": "f12220f303e0d7c0844c0e5e957b0c3cee48d2f7", "shasum": "" }, "conflict": { @@ -1814,9 +1810,10 @@ "nikic/php-parser": "^5.5", "php": "^7.4 || ^8.0", "php-stubs/generator": "^0.8.3", - "phpdocumentor/reflection-docblock": "^5.4.1", + "phpdocumentor/reflection-docblock": "^6.0", "phpstan/phpstan": "^2.1", "phpunit/phpunit": "^9.5", + "symfony/polyfill-php80": "*", "szepeviktor/phpcs-psr-12-neutron-hybrid-ruleset": "^1.1.1", "wp-coding-standards/wpcs": "3.1.0 as 2.3.0" }, @@ -1839,9 +1836,9 @@ ], "support": { "issues": "https://github.com/php-stubs/wordpress-stubs/issues", - "source": "https://github.com/php-stubs/wordpress-stubs/tree/v6.8.3" + "source": "https://github.com/php-stubs/wordpress-stubs/tree/v6.9.1" }, - "time": "2025-09-30T20:58:47+00:00" + "time": "2026-02-03T19:29:21+00:00" }, { "name": "phpcompatibility/php-compatibility", @@ -2140,16 +2137,16 @@ }, { "name": "phpcsstandards/phpcsutils", - "version": "1.2.1", + "version": "1.2.2", "source": { "type": "git", "url": "https://github.com/PHPCSStandards/PHPCSUtils.git", - "reference": "d71128c702c180ca3b27c761b6773f883394f162" + "reference": "c216317e96c8b3f5932808f9b0f1f7a14e3bbf55" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/PHPCSUtils/zipball/d71128c702c180ca3b27c761b6773f883394f162", - "reference": "d71128c702c180ca3b27c761b6773f883394f162", + "url": "https://api.github.com/repos/PHPCSStandards/PHPCSUtils/zipball/c216317e96c8b3f5932808f9b0f1f7a14e3bbf55", + "reference": "c216317e96c8b3f5932808f9b0f1f7a14e3bbf55", "shasum": "" }, "require": { @@ -2229,7 +2226,7 @@ "type": "thanks_dev" } ], - "time": "2025-11-17T12:58:33+00:00" + "time": "2025-12-08T14:27:58+00:00" }, { "name": "phpdocumentor/reflection-common", @@ -2286,16 +2283,16 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "5.6.3", + "version": "5.6.7", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "94f8051919d1b0369a6bcc7931d679a511c03fe9" + "reference": "31a105931bc8ffa3a123383829772e832fd8d903" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/94f8051919d1b0369a6bcc7931d679a511c03fe9", - "reference": "94f8051919d1b0369a6bcc7931d679a511c03fe9", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/31a105931bc8ffa3a123383829772e832fd8d903", + "reference": "31a105931bc8ffa3a123383829772e832fd8d903", "shasum": "" }, "require": { @@ -2305,7 +2302,7 @@ "phpdocumentor/reflection-common": "^2.2", "phpdocumentor/type-resolver": "^1.7", "phpstan/phpdoc-parser": "^1.7|^2.0", - "webmozart/assert": "^1.9.1" + "webmozart/assert": "^1.9.1 || ^2" }, "require-dev": { "mockery/mockery": "~1.3.5 || ~1.6.0", @@ -2344,22 +2341,22 @@ "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", "support": { "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.3" + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.7" }, - "time": "2025-08-01T19:43:32+00:00" + "time": "2026-03-18T20:47:46+00:00" }, { "name": "phpdocumentor/type-resolver", - "version": "1.10.0", + "version": "1.12.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "679e3ce485b99e84c775d28e2e96fade9a7fb50a" + "reference": "92a98ada2b93d9b201a613cb5a33584dde25f195" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/679e3ce485b99e84c775d28e2e96fade9a7fb50a", - "reference": "679e3ce485b99e84c775d28e2e96fade9a7fb50a", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/92a98ada2b93d9b201a613cb5a33584dde25f195", + "reference": "92a98ada2b93d9b201a613cb5a33584dde25f195", "shasum": "" }, "require": { @@ -2402,9 +2399,9 @@ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "support": { "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.10.0" + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.12.0" }, - "time": "2024-11-09T15:12:26+00:00" + "time": "2025-11-21T15:09:14+00:00" }, { "name": "phpmd/phpmd", @@ -2539,16 +2536,16 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "2.3.0", + "version": "2.3.2", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "1e0cd5370df5dd2e556a36b9c62f62e555870495" + "reference": "a004701b11273a26cd7955a61d67a7f1e525a45a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/1e0cd5370df5dd2e556a36b9c62f62e555870495", - "reference": "1e0cd5370df5dd2e556a36b9c62f62e555870495", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/a004701b11273a26cd7955a61d67a7f1e525a45a", + "reference": "a004701b11273a26cd7955a61d67a7f1e525a45a", "shasum": "" }, "require": { @@ -2580,17 +2577,17 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/2.3.0" + "source": "https://github.com/phpstan/phpdoc-parser/tree/2.3.2" }, - "time": "2025-08-30T15:50:23+00:00" + "time": "2026-01-25T14:56:51+00:00" }, { "name": "phpstan/phpstan", - "version": "2.1.32", + "version": "2.1.54", "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/e126cad1e30a99b137b8ed75a85a676450ebb227", - "reference": "e126cad1e30a99b137b8ed75a85a676450ebb227", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/8be50c3992107dc837b17da4d140fbbdf9a5c5bd", + "reference": "8be50c3992107dc837b17da4d140fbbdf9a5c5bd", "shasum": "" }, "require": { @@ -2635,7 +2632,7 @@ "type": "github" } ], - "time": "2025-11-11T15:18:17+00:00" + "time": "2026-04-29T13:31:09+00:00" }, { "name": "psr/container", @@ -2895,6 +2892,57 @@ }, "time": "2021-05-03T11:20:27+00:00" }, + { + "name": "psr/simple-cache", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/simple-cache.git", + "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", + "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\SimpleCache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interfaces for simple caching", + "keywords": [ + "cache", + "caching", + "psr", + "psr-16", + "simple-cache" + ], + "support": { + "source": "https://github.com/php-fig/simple-cache/tree/master" + }, + "time": "2017-10-23T01:57:42+00:00" + }, { "name": "ralouphie/getallheaders", "version": "3.0.3", @@ -3008,16 +3056,16 @@ }, { "name": "spatie/array-to-xml", - "version": "3.4.1", + "version": "3.4.4", "source": { "type": "git", "url": "https://github.com/spatie/array-to-xml.git", - "reference": "6a740f39415aee8886aea10333403adc77d50791" + "reference": "88b2f3852a922dd73177a68938f8eb2ec70c7224" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/array-to-xml/zipball/6a740f39415aee8886aea10333403adc77d50791", - "reference": "6a740f39415aee8886aea10333403adc77d50791", + "url": "https://api.github.com/repos/spatie/array-to-xml/zipball/88b2f3852a922dd73177a68938f8eb2ec70c7224", + "reference": "88b2f3852a922dd73177a68938f8eb2ec70c7224", "shasum": "" }, "require": { @@ -3060,7 +3108,7 @@ "xml" ], "support": { - "source": "https://github.com/spatie/array-to-xml/tree/3.4.1" + "source": "https://github.com/spatie/array-to-xml/tree/3.4.4" }, "funding": [ { @@ -3072,7 +3120,7 @@ "type": "github" } ], - "time": "2025-11-12T10:32:50+00:00" + "time": "2025-12-15T09:00:41+00:00" }, { "name": "squizlabs/php_codesniffer", @@ -3155,16 +3203,16 @@ }, { "name": "symfony/config", - "version": "v6.4.28", + "version": "v6.4.37", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "15947c18ef3ddb0b2f4ec936b9e90e2520979f62" + "reference": "ee615e8352db9c5f0b7b149154a3f654dc72042b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/15947c18ef3ddb0b2f4ec936b9e90e2520979f62", - "reference": "15947c18ef3ddb0b2f4ec936b9e90e2520979f62", + "url": "https://api.github.com/repos/symfony/config/zipball/ee615e8352db9c5f0b7b149154a3f654dc72042b", + "reference": "ee615e8352db9c5f0b7b149154a3f654dc72042b", "shasum": "" }, "require": { @@ -3210,7 +3258,7 @@ "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/config/tree/v6.4.28" + "source": "https://github.com/symfony/config/tree/v6.4.37" }, "funding": [ { @@ -3230,7 +3278,7 @@ "type": "tidelift" } ], - "time": "2025-11-01T19:52:02+00:00" + "time": "2026-04-29T10:19:30+00:00" }, { "name": "symfony/console", @@ -3333,16 +3381,16 @@ }, { "name": "symfony/dependency-injection", - "version": "v6.4.26", + "version": "v6.4.38", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "5f311eaf0b321f8ec640f6bae12da43a14026898" + "reference": "f0990df92ee67721886a2a8b6e19a1bafbf3d7a4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/5f311eaf0b321f8ec640f6bae12da43a14026898", - "reference": "5f311eaf0b321f8ec640f6bae12da43a14026898", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/f0990df92ee67721886a2a8b6e19a1bafbf3d7a4", + "reference": "f0990df92ee67721886a2a8b6e19a1bafbf3d7a4", "shasum": "" }, "require": { @@ -3394,7 +3442,7 @@ "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dependency-injection/tree/v6.4.26" + "source": "https://github.com/symfony/dependency-injection/tree/v6.4.38" }, "funding": [ { @@ -3414,20 +3462,20 @@ "type": "tidelift" } ], - "time": "2025-09-11T09:57:09+00:00" + "time": "2026-05-04T13:00:01+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v3.6.0", + "version": "v3.7.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62" + "reference": "50f59d1f3ca46d41ac911f97a78626b6756af35b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/63afe740e99a13ba87ec199bb07bbdee937a5b62", - "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/50f59d1f3ca46d41ac911f97a78626b6756af35b", + "reference": "50f59d1f3ca46d41ac911f97a78626b6756af35b", "shasum": "" }, "require": { @@ -3440,7 +3488,7 @@ "name": "symfony/contracts" }, "branch-alias": { - "dev-main": "3.6-dev" + "dev-main": "3.7-dev" } }, "autoload": { @@ -3465,7 +3513,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.6.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.7.0" }, "funding": [ { @@ -3476,25 +3524,29 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2024-09-25T14:21:43+00:00" + "time": "2026-04-13T15:52:40+00:00" }, { "name": "symfony/filesystem", - "version": "v6.4.24", + "version": "v6.4.37", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "75ae2edb7cdcc0c53766c30b0a2512b8df574bd8" + "reference": "29f792d7dc30cc670fc4cdd50d7c6653d067ce7b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/75ae2edb7cdcc0c53766c30b0a2512b8df574bd8", - "reference": "75ae2edb7cdcc0c53766c30b0a2512b8df574bd8", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/29f792d7dc30cc670fc4cdd50d7c6653d067ce7b", + "reference": "29f792d7dc30cc670fc4cdd50d7c6653d067ce7b", "shasum": "" }, "require": { @@ -3531,7 +3583,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v6.4.24" + "source": "https://github.com/symfony/filesystem/tree/v6.4.37" }, "funding": [ { @@ -3551,7 +3603,7 @@ "type": "tidelift" } ], - "time": "2025-07-10T08:14:14+00:00" + "time": "2026-04-13T15:27:04+00:00" }, { "name": "symfony/finder", @@ -3618,16 +3670,16 @@ }, { "name": "symfony/http-client", - "version": "v6.4.28", + "version": "v6.4.37", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "c9e69c185c4a845f9d46958cdb0dc7aa847f3981" + "reference": "d40d3ac56e549056fedfb257fa58395b74cf964d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/c9e69c185c4a845f9d46958cdb0dc7aa847f3981", - "reference": "c9e69c185c4a845f9d46958cdb0dc7aa847f3981", + "url": "https://api.github.com/repos/symfony/http-client/zipball/d40d3ac56e549056fedfb257fa58395b74cf964d", + "reference": "d40d3ac56e549056fedfb257fa58395b74cf964d", "shasum": "" }, "require": { @@ -3692,7 +3744,7 @@ "http" ], "support": { - "source": "https://github.com/symfony/http-client/tree/v6.4.28" + "source": "https://github.com/symfony/http-client/tree/v6.4.37" }, "funding": [ { @@ -3712,20 +3764,20 @@ "type": "tidelift" } ], - "time": "2025-11-05T17:39:22+00:00" + "time": "2026-04-29T06:37:06+00:00" }, { "name": "symfony/http-client-contracts", - "version": "v3.6.0", + "version": "v3.7.0", "source": { "type": "git", "url": "https://github.com/symfony/http-client-contracts.git", - "reference": "75d7043853a42837e68111812f4d964b01e5101c" + "reference": "4a2d00c37651c0bdc2b9e1c773487a8bf4edb12d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/75d7043853a42837e68111812f4d964b01e5101c", - "reference": "75d7043853a42837e68111812f4d964b01e5101c", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/4a2d00c37651c0bdc2b9e1c773487a8bf4edb12d", + "reference": "4a2d00c37651c0bdc2b9e1c773487a8bf4edb12d", "shasum": "" }, "require": { @@ -3738,7 +3790,7 @@ "name": "symfony/contracts" }, "branch-alias": { - "dev-main": "3.6-dev" + "dev-main": "3.7-dev" } }, "autoload": { @@ -3774,7 +3826,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/http-client-contracts/tree/v3.6.0" + "source": "https://github.com/symfony/http-client-contracts/tree/v3.7.0" }, "funding": [ { @@ -3785,25 +3837,29 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2025-04-29T11:18:49+00:00" + "time": "2026-03-06T13:17:50+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.33.0", + "version": "v1.37.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" + "reference": "141046a8f9477948ff284fa65be2095baafb94f2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", - "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/141046a8f9477948ff284fa65be2095baafb94f2", + "reference": "141046a8f9477948ff284fa65be2095baafb94f2", "shasum": "" }, "require": { @@ -3853,7 +3909,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.37.0" }, "funding": [ { @@ -3873,20 +3929,20 @@ "type": "tidelift" } ], - "time": "2024-09-09T11:45:10+00:00" + "time": "2026-04-10T16:19:22+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.33.0", + "version": "v1.37.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70" + "reference": "4864388bfbd3001ce88e234fab652acd91fdc57e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/380872130d3a5dd3ace2f4010d95125fde5d5c70", - "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/4864388bfbd3001ce88e234fab652acd91fdc57e", + "reference": "4864388bfbd3001ce88e234fab652acd91fdc57e", "shasum": "" }, "require": { @@ -3935,7 +3991,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.37.0" }, "funding": [ { @@ -3955,11 +4011,11 @@ "type": "tidelift" } ], - "time": "2025-06-27T09:58:17+00:00" + "time": "2026-04-26T13:13:48+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.33.0", + "version": "v1.37.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", @@ -4020,7 +4076,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.37.0" }, "funding": [ { @@ -4044,16 +4100,16 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.33.0", + "version": "v1.37.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493" + "reference": "6a21eb99c6973357967f6ce3708cd55a6bec6315" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493", - "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6a21eb99c6973357967f6ce3708cd55a6bec6315", + "reference": "6a21eb99c6973357967f6ce3708cd55a6bec6315", "shasum": "" }, "require": { @@ -4105,7 +4161,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.37.0" }, "funding": [ { @@ -4125,11 +4181,11 @@ "type": "tidelift" } ], - "time": "2024-12-23T08:48:59+00:00" + "time": "2026-04-10T17:25:58+00:00" }, { "name": "symfony/polyfill-php73", - "version": "v1.33.0", + "version": "v1.37.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", @@ -4185,7 +4241,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php73/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-php73/tree/v1.37.0" }, "funding": [ { @@ -4209,16 +4265,16 @@ }, { "name": "symfony/polyfill-php80", - "version": "v1.33.0", + "version": "v1.37.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608" + "reference": "dfb55726c3a76ea3b6459fcfda1ec2d80a682411" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/0cc9dd0f17f61d8131e7df6b84bd344899fe2608", - "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/dfb55726c3a76ea3b6459fcfda1ec2d80a682411", + "reference": "dfb55726c3a76ea3b6459fcfda1ec2d80a682411", "shasum": "" }, "require": { @@ -4269,7 +4325,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.37.0" }, "funding": [ { @@ -4289,20 +4345,20 @@ "type": "tidelift" } ], - "time": "2025-01-02T08:10:11+00:00" + "time": "2026-04-10T16:19:22+00:00" }, { "name": "symfony/polyfill-php83", - "version": "v1.33.0", + "version": "v1.37.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php83.git", - "reference": "17f6f9a6b1735c0f163024d959f700cfbc5155e5" + "reference": "3600c2cb22399e25bb226e4a135ce91eeb2a6149" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/17f6f9a6b1735c0f163024d959f700cfbc5155e5", - "reference": "17f6f9a6b1735c0f163024d959f700cfbc5155e5", + "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/3600c2cb22399e25bb226e4a135ce91eeb2a6149", + "reference": "3600c2cb22399e25bb226e4a135ce91eeb2a6149", "shasum": "" }, "require": { @@ -4349,7 +4405,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php83/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-php83/tree/v1.37.0" }, "funding": [ { @@ -4369,20 +4425,20 @@ "type": "tidelift" } ], - "time": "2025-07-08T02:45:35+00:00" + "time": "2026-04-10T17:25:58+00:00" }, { "name": "symfony/service-contracts", - "version": "v3.6.1", + "version": "v3.7.0", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "45112560a3ba2d715666a509a0bc9521d10b6c43" + "reference": "d25d82433a80eba6aa0e6c24b61d7370d99e444a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/45112560a3ba2d715666a509a0bc9521d10b6c43", - "reference": "45112560a3ba2d715666a509a0bc9521d10b6c43", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/d25d82433a80eba6aa0e6c24b61d7370d99e444a", + "reference": "d25d82433a80eba6aa0e6c24b61d7370d99e444a", "shasum": "" }, "require": { @@ -4400,7 +4456,7 @@ "name": "symfony/contracts" }, "branch-alias": { - "dev-main": "3.6-dev" + "dev-main": "3.7-dev" } }, "autoload": { @@ -4436,7 +4492,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.6.1" + "source": "https://github.com/symfony/service-contracts/tree/v3.7.0" }, "funding": [ { @@ -4456,20 +4512,20 @@ "type": "tidelift" } ], - "time": "2025-07-15T11:30:57+00:00" + "time": "2026-03-28T09:44:51+00:00" }, { "name": "symfony/string", - "version": "v6.4.26", + "version": "v6.4.34", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "5621f039a71a11c87c106c1c598bdcd04a19aeea" + "reference": "2adaf4106f2ef4c67271971bde6d3fe0a6936432" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/5621f039a71a11c87c106c1c598bdcd04a19aeea", - "reference": "5621f039a71a11c87c106c1c598bdcd04a19aeea", + "url": "https://api.github.com/repos/symfony/string/zipball/2adaf4106f2ef4c67271971bde6d3fe0a6936432", + "reference": "2adaf4106f2ef4c67271971bde6d3fe0a6936432", "shasum": "" }, "require": { @@ -4525,7 +4581,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v6.4.26" + "source": "https://github.com/symfony/string/tree/v6.4.34" }, "funding": [ { @@ -4545,20 +4601,20 @@ "type": "tidelift" } ], - "time": "2025-09-11T14:32:46+00:00" + "time": "2026-02-08T20:44:54+00:00" }, { "name": "symfony/var-exporter", - "version": "v6.4.26", + "version": "v6.4.37", "source": { "type": "git", "url": "https://github.com/symfony/var-exporter.git", - "reference": "466fcac5fa2e871f83d31173f80e9c2684743bfc" + "reference": "34f6957deffacabd1b1c579a312daa481e3e99ca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-exporter/zipball/466fcac5fa2e871f83d31173f80e9c2684743bfc", - "reference": "466fcac5fa2e871f83d31173f80e9c2684743bfc", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/34f6957deffacabd1b1c579a312daa481e3e99ca", + "reference": "34f6957deffacabd1b1c579a312daa481e3e99ca", "shasum": "" }, "require": { @@ -4606,7 +4662,7 @@ "serialize" ], "support": { - "source": "https://github.com/symfony/var-exporter/tree/v6.4.26" + "source": "https://github.com/symfony/var-exporter/tree/v6.4.37" }, "funding": [ { @@ -4626,7 +4682,7 @@ "type": "tidelift" } ], - "time": "2025-09-11T09:57:09+00:00" + "time": "2026-04-14T12:12:40+00:00" }, { "name": "szepeviktor/phpstan-wordpress", @@ -4861,16 +4917,16 @@ }, { "name": "wp-coding-standards/wpcs", - "version": "3.2.0", + "version": "3.3.0", "source": { "type": "git", "url": "https://github.com/WordPress/WordPress-Coding-Standards.git", - "reference": "d2421de7cec3274ae622c22c744de9a62c7925af" + "reference": "7795ec6fa05663d716a549d0b44e47ffc8b0d4a6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/WordPress/WordPress-Coding-Standards/zipball/d2421de7cec3274ae622c22c744de9a62c7925af", - "reference": "d2421de7cec3274ae622c22c744de9a62c7925af", + "url": "https://api.github.com/repos/WordPress/WordPress-Coding-Standards/zipball/7795ec6fa05663d716a549d0b44e47ffc8b0d4a6", + "reference": "7795ec6fa05663d716a549d0b44e47ffc8b0d4a6", "shasum": "" }, "require": { @@ -4878,17 +4934,17 @@ "ext-libxml": "*", "ext-tokenizer": "*", "ext-xmlreader": "*", - "php": ">=5.4", - "phpcsstandards/phpcsextra": "^1.4.0", + "php": ">=7.2", + "phpcsstandards/phpcsextra": "^1.5.0", "phpcsstandards/phpcsutils": "^1.1.0", - "squizlabs/php_codesniffer": "^3.13.0" + "squizlabs/php_codesniffer": "^3.13.4" }, "require-dev": { "php-parallel-lint/php-console-highlighter": "^1.0.0", "php-parallel-lint/php-parallel-lint": "^1.4.0", - "phpcompatibility/php-compatibility": "^9.0", + "phpcompatibility/php-compatibility": "^10.0.0@dev", "phpcsstandards/phpcsdevtools": "^1.2.0", - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0" + "phpunit/phpunit": "^8.0 || ^9.0" }, "suggest": { "ext-iconv": "For improved results", @@ -4923,7 +4979,7 @@ "type": "custom" } ], - "time": "2025-07-24T20:08:31+00:00" + "time": "2025-11-25T12:08:04+00:00" } ], "aliases": [], diff --git a/includes/AI/AI_API.php b/includes/AI/AI_API.php index 7b77915..22f2f77 100644 --- a/includes/AI/AI_API.php +++ b/includes/AI/AI_API.php @@ -121,7 +121,7 @@ private function init_ai(): ?AI { private function get_ai_setting( string $key ) { $settings = Emoji::decode_array( $this->settings->get() ); - $ai_settings = $settings['pressidium_options']['ai'] ?? array(); + $ai_settings = $settings['pressidiumOptions']['ai'] ?? array(); return $ai_settings[ $key ] ?? null; } @@ -137,10 +137,10 @@ private function get_ai_setting( string $key ) { private function update_ai_setting( string $key, $value ): bool { $settings = Emoji::decode_array( $this->settings->get() ); - $ai_settings = $settings['pressidium_options']['ai'] ?? array(); + $ai_settings = $settings['pressidiumOptions']['ai'] ?? array(); $ai_settings[ $key ] = $value; - $settings['pressidium_options']['ai'] = $ai_settings; + $settings['pressidiumOptions']['ai'] = $ai_settings; return $this->settings->set( $settings ); } diff --git a/includes/Admin/Settings/Service_Provider.php b/includes/Admin/Settings/Service_Provider.php index 9666be1..4d33f8d 100644 --- a/includes/Admin/Settings/Service_Provider.php +++ b/includes/Admin/Settings/Service_Provider.php @@ -56,7 +56,8 @@ public function register(): void { ->addArgument( $this->getContainer()->get( 'logs' ) ) ->addArgument( $this->getContainer()->get( 'geo_locator' ) ) ->addArgument( $this->getContainer()->get( 'consents_table' ) ) - ->addArgument( $this->getContainer()->get( 'db_table_exporter' ) ); + ->addArgument( $this->getContainer()->get( 'db_table_exporter' ) ) + ->addArgument( $this->getContainer()->get( 'rate_limiter' ) ); } } diff --git a/includes/Admin/Settings/Settings_API.php b/includes/Admin/Settings/Settings_API.php index 2a7f507..ca92c8f 100644 --- a/includes/Admin/Settings/Settings_API.php +++ b/includes/Admin/Settings/Settings_API.php @@ -18,6 +18,7 @@ use Pressidium\WP\CookieConsent\Geo_Locator; use Pressidium\WP\CookieConsent\Database\Tables\Consents_Table; use Pressidium\WP\CookieConsent\Utils\Date_Utils; +use Pressidium\WP\CookieConsent\Rate_Limiting\Rate_Limiter; use WP_REST_Request; use WP_REST_Response; @@ -73,14 +74,20 @@ class Settings_API implements Actions { */ private Exporter $exporter; + /** + * @var Rate_Limiter Instance of `Rate_Limiter`. + */ + private Rate_Limiter $rate_limiter; + /** * Settings_API constructor. * - * @param Settings $settings - * @param Logger $logger - * @param Logs $logs - * @param Geo_Locator $geo_locator - * @param Exporter $exporter + * @param Settings $settings + * @param Logger $logger + * @param Logs $logs + * @param Geo_Locator $geo_locator + * @param Exporter $exporter + * @param Rate_Limiter $rate_limiter */ public function __construct( Settings $settings, @@ -88,7 +95,8 @@ public function __construct( Logs $logs, Geo_Locator $geo_locator, Consents_Table $consents_table, - Exporter $exporter + Exporter $exporter, + Rate_Limiter $rate_limiter ) { $this->settings = $settings; $this->logger = $logger; @@ -96,6 +104,7 @@ public function __construct( $this->geo_locator = $geo_locator; $this->consents_table = $consents_table; $this->exporter = $exporter; + $this->rate_limiter = $rate_limiter; } /** @@ -109,206 +118,244 @@ private function get_settings_schema(): array { return array( 'type' => 'object', 'required' => array( - 'autorun', - 'force_consent', - 'autoclear_cookies', - 'page_scripts', - 'hide_from_bots', + 'autoShow', + 'disablePageInteraction', + 'autoClearCookies', + 'manageScriptTags', + 'hideFromBots', 'reconsent', - 'delay', - 'cookie_expiration', - 'cookie_path', - 'cookie_domain', - 'auto_language', - 'languages', - 'gui_options', - 'pressidium_options', + 'cookie', + 'categories', + 'language', + 'guiOptions', + 'pressidiumOptions', ), 'properties' => array( - 'autorun' => array( + 'autoShow' => array( 'type' => 'boolean', ), - 'force_consent' => array( + 'disablePageInteraction' => array( 'type' => 'boolean', ), - 'autoclear_cookies' => array( + 'autoClearCookies' => array( 'type' => 'boolean', ), - 'page_scripts' => array( + 'manageScriptTags' => array( 'type' => 'boolean', ), - 'hide_from_bots' => array( + 'hideFromBots' => array( 'type' => 'boolean', ), 'reconsent' => array( 'type' => 'boolean', ), - 'delay' => array( - 'type' => 'integer', - ), - 'cookie_expiration' => array( - 'type' => 'integer', - ), - 'cookie_path' => array( - 'type' => 'string', - ), - 'cookie_domain' => array( - 'type' => 'string', - ), - 'auto_language' => array( - 'type' => 'string', + 'cookie' => array( + 'type' => 'object', + 'required' => array( + 'expiresAfterDays', + 'path', + 'domain', + 'name', + ), + 'properties' => array( + 'expiresAfterDays' => array( + 'type' => 'integer', + ), + 'path' => array( + 'type' => 'string', + ), + 'domain' => array( + 'type' => 'string', + ), + 'name' => array( + 'type' => 'string', + ), + ), ), - 'languages' => array( + 'categories' => array( 'type' => 'object', + 'required' => array( + 'necessary', + 'analytics', + 'targeting', + 'preferences', + ), 'properties' => array( - '[a-zA-Z]' => array( + 'necessary' => array( 'type' => 'object', 'required' => array( - 'consent_modal', - 'settings_modal', + 'enabled', + 'readOnly', ), 'properties' => array( - 'consent_modal' => array( + 'enabled' => array( + 'type' => 'boolean', + ), + 'readOnly' => array( + 'type' => 'boolean', + ), + ), + ), + 'analytics' => array( + 'type' => 'object', + 'required' => array( + 'enabled', + 'readOnly', + ), + 'properties' => array( + 'enabled' => array( + 'type' => 'boolean', + ), + 'readOnly' => array( + 'type' => 'boolean', + ), + ), + ), + 'targeting' => array( + 'type' => 'object', + 'required' => array( + 'enabled', + 'readOnly', + ), + 'properties' => array( + 'enabled' => array( + 'type' => 'boolean', + ), + 'readOnly' => array( + 'type' => 'boolean', + ), + ), + ), + 'preferences' => array( + 'type' => 'object', + 'required' => array( + 'enabled', + 'readOnly', + ), + 'properties' => array( + 'enabled' => array( + 'type' => 'boolean', + ), + 'readOnly' => array( + 'type' => 'boolean', + ), + ), + ), + ), + ), + 'language' => array( + 'type' => 'object', + 'required' => array( + 'default', + 'autoDetect', + 'translations', + ), + 'properties' => array( + 'default' => array( + 'type' => 'string', + ), + 'autoDetect' => array( + 'type' => 'string', + ), + 'translations' => array( + 'type' => 'object', + 'properties' => array( + '[a-zA-Z]' => array( 'type' => 'object', 'required' => array( - 'title', - 'description', - 'primary_btn', - 'secondary_btn', + 'consentModal', + 'preferencesModal', ), 'properties' => array( - 'title' => array( - 'type' => 'string', - ), - 'description' => array( - 'type' => 'string', - ), - 'primary_btn' => array( + 'consentModal' => array( 'type' => 'object', 'required' => array( - 'text', - 'role', + 'title', + 'description', + 'acceptAllBtn', + 'acceptNecessaryBtn', + 'showPreferencesBtn', ), 'properties' => array( - 'text' => array( + 'title' => array( + 'type' => 'string', + ), + 'description' => array( 'type' => 'string', ), - 'role' => array( + 'acceptAllBtn' => array( 'type' => 'string', ), + 'acceptNecessaryBtn' => array( + 'type' => 'string', + ), + 'showPreferencesBtn' => array( + 'type' => 'string', + ), + 'closeIconLabel' => array( + 'type' => array( 'string', 'null' ), + ), + 'footer' => array( + 'type' => 'string', + ), + 'footerLinks' => array( + 'type' => 'array', + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'url' => array( 'type' => 'string' ), + 'label' => array( 'type' => 'string' ), + ), + ), + ), ), ), - 'secondary_btn' => array( + 'preferencesModal' => array( 'type' => 'object', 'required' => array( - 'text', - 'role', + 'title', + 'savePreferencesBtn', + 'acceptAllBtn', + 'acceptNecessaryBtn', + 'closeIconLabel', + 'sections', ), 'properties' => array( - 'text' => array( + 'title' => array( 'type' => 'string', ), - 'role' => array( + 'savePreferencesBtn' => array( 'type' => 'string', ), - ), - ), - ), - ), - 'settings_modal' => array( - 'type' => 'object', - 'required' => array( - 'title', - 'save_settings_btn', - 'accept_all_btn', - 'reject_all_btn', - 'close_btn_label', - 'cookie_table_headers', - 'blocks', - ), - 'properties' => array( - 'title' => array( - 'type' => 'string', - ), - 'save_settings_btn' => array( - 'type' => 'string', - ), - 'accept_all_btn' => array( - 'type' => 'string', - ), - 'reject_all_btn' => array( - 'type' => 'string', - ), - 'close_btn_label' => array( - 'type' => 'string', - ), - 'cookie_table_headers' => array( - 'type' => 'array', - 'items' => array( - 'type' => 'object', - 'required' => array( - 'name', - 'domain', - 'expiration', - 'path', - 'description', + 'acceptAllBtn' => array( + 'type' => 'string', ), - 'properties' => array( - 'name' => array( - 'type' => 'string', - ), - 'domain' => array( - 'type' => 'string', - ), - 'expiration' => array( - 'type' => 'string', - ), - 'path' => array( - 'type' => 'string', - ), - 'description' => array( - 'type' => 'string', - ), + 'acceptNecessaryBtn' => array( + 'type' => 'string', ), - ), - ), - 'blocks' => array( - 'type' => 'array', - 'items' => array( - 'type' => 'object', - 'required' => array( - 'title', - 'description', + 'closeIconLabel' => array( + 'type' => 'string', ), - 'properties' => array( - 'title' => array( - 'type' => 'string', - ), - 'description' => array( - 'type' => 'string', - ), - 'toggle' => array( + 'sections' => array( + 'type' => 'array', + 'items' => array( 'type' => 'object', 'required' => array( - 'value', - 'enabled', - 'readonly', + 'title', + 'description', ), 'properties' => array( - 'value' => array( + 'title' => array( 'type' => 'string', ), - 'enabled' => array( - 'type' => 'boolean', + 'description' => array( + 'type' => 'string', ), - 'readonly' => array( - 'type' => 'boolean', + 'linkedCategory' => array( + 'type' => 'string', ), ), ), - 'cookie_table' => array( - 'type' => 'array', - ), ), ), ), @@ -318,20 +365,20 @@ private function get_settings_schema(): array { ), ), ), - 'gui_options' => array( + 'guiOptions' => array( 'type' => 'object', 'required' => array( - 'consent_modal', - 'settings_modal', + 'consentModal', + 'preferencesModal', ), 'properties' => array( - 'consent_modal' => array( + 'consentModal' => array( 'type' => 'object', 'required' => array( 'layout', 'position', - 'transition', - 'swap_buttons', + 'equalWeightButtons', + 'flipButtons', ), 'properties' => array( 'layout' => array( @@ -343,17 +390,21 @@ private function get_settings_schema(): array { 'transition' => array( 'type' => 'string', ), - 'swap_buttons' => array( + 'equalWeightButtons' => array( + 'type' => 'boolean', + ), + 'flipButtons' => array( 'type' => 'boolean', ), ), ), - 'settings_modal' => array( + 'preferencesModal' => array( 'type' => 'object', 'required' => array( 'layout', 'position', - 'transition', + 'equalWeightButtons', + 'flipButtons', ), 'properties' => array( 'layout' => array( @@ -362,32 +413,29 @@ private function get_settings_schema(): array { 'position' => array( 'type' => 'string', ), - 'transition' => array( - 'type' => 'string', + 'equalWeightButtons' => array( + 'type' => 'boolean', + ), + 'flipButtons' => array( + 'type' => 'boolean', ), ), ), ), ), - 'pressidium_options' => array( + 'pressidiumOptions' => array( 'type' => 'object', 'required' => array( - 'primary_btn_role', - 'secondary_btn_role', - 'cookie_table', + 'cookieTable', + 'cookieTableHeaders', + 'blockedScripts', 'font', - 'floating_button', + 'floatingButton', 'colors', 'gcm', ), 'properties' => array( - 'primary_btn_role' => array( - 'type' => 'string', - ), - 'secondary_btn_role' => array( - 'type' => 'string', - ), - 'cookie_table' => array( + 'cookieTable' => array( 'type' => 'object', 'required' => array( 'necessary', @@ -406,7 +454,7 @@ private function get_settings_schema(): array { 'expiration', 'path', 'description', - 'is_regex', + 'isRegex', ), 'properties' => array( 'name' => array( @@ -424,7 +472,7 @@ private function get_settings_schema(): array { 'description' => array( 'type' => 'string', ), - 'is_regex' => array( + 'isRegex' => array( 'type' => 'boolean', ), ), @@ -440,7 +488,7 @@ private function get_settings_schema(): array { 'expiration', 'path', 'description', - 'is_regex', + 'isRegex', ), 'properties' => array( 'name' => array( @@ -458,7 +506,7 @@ private function get_settings_schema(): array { 'description' => array( 'type' => 'string', ), - 'is_regex' => array( + 'isRegex' => array( 'type' => 'boolean', ), ), @@ -474,7 +522,7 @@ private function get_settings_schema(): array { 'expiration', 'path', 'description', - 'is_regex', + 'isRegex', ), 'properties' => array( 'name' => array( @@ -492,7 +540,7 @@ private function get_settings_schema(): array { 'description' => array( 'type' => 'string', ), - 'is_regex' => array( + 'isRegex' => array( 'type' => 'boolean', ), ), @@ -508,7 +556,7 @@ private function get_settings_schema(): array { 'expiration', 'path', 'description', - 'is_regex', + 'isRegex', ), 'properties' => array( 'name' => array( @@ -526,7 +574,7 @@ private function get_settings_schema(): array { 'description' => array( 'type' => 'string', ), - 'is_regex' => array( + 'isRegex' => array( 'type' => 'boolean', ), ), @@ -534,6 +582,68 @@ private function get_settings_schema(): array { ), ), ), + 'cookieTableHeaders' => array( + 'type' => 'object', + 'required' => array( + 'translations', + ), + 'properties' => array( + 'translations' => array( + 'type' => 'object', + 'properties' => array( + '[a-zA-Z]' => array( + 'type' => 'object', + 'required' => array( + 'name', + 'domain', + 'expiration', + 'path', + 'description', + ), + 'properties' => array( + 'name' => array( + 'type' => 'string', + ), + 'domain' => array( + 'type' => 'string', + ), + 'expiration' => array( + 'type' => 'string', + ), + 'path' => array( + 'type' => 'string', + ), + 'description' => array( + 'type' => 'string', + ), + ), + ), + ), + ), + ), + ), + 'blockedScripts' => array( + 'type' => 'array', + 'items' => array( + 'type' => 'object', + 'required' => array( + 'src', + 'category', + 'isRegex', + ), + 'properties' => array( + 'src' => array( + 'type' => 'string', + ), + 'category' => array( + 'type' => 'string', + ), + 'isRegex' => array( + 'type' => 'boolean', + ), + ), + ), + ), 'font' => array( 'type' => 'object', 'required' => array( @@ -542,7 +652,7 @@ private function get_settings_schema(): array { 'family', ), ), - 'floating_button' => array( + 'floatingButton' => array( 'type' => 'object', 'required' => array( 'enabled', @@ -556,23 +666,23 @@ private function get_settings_schema(): array { 'type' => 'object', 'required' => array( 'bg', - 'text', + 'primary-color', 'btn-primary-bg', - 'btn-primary-text', + 'btn-primary-color', 'btn-primary-hover-bg', - 'btn-primary-hover-text', + 'btn-primary-hover-color', 'btn-secondary-bg', - 'btn-secondary-text', + 'btn-secondary-color', 'btn-secondary-hover-bg', - 'btn-secondary-hover-text', - 'toggle-bg-off', - 'toggle-bg-on', - 'toggle-bg-readonly', + 'btn-secondary-hover-color', + 'toggle-off-bg', + 'toggle-on-knob-bg', + 'toggle-readonly-bg', 'toggle-knob-bg', 'toggle-knob-icon-color', 'cookie-category-block-bg', - 'cookie-category-block-bg-hover', - 'section-border', + 'cookie-category-block-hover-bg', + 'separator-border-color', 'block-text', 'cookie-table-border', 'overlay-bg', @@ -587,40 +697,40 @@ private function get_settings_schema(): array { 'bg' => array( 'type' => 'string', ), - 'text' => array( + 'primary-color' => array( 'type' => 'string', ), 'btn-primary-bg' => array( 'type' => 'string', ), - 'btn-primary-text' => array( + 'btn-primary-color' => array( 'type' => 'string', ), 'btn-primary-hover-bg' => array( 'type' => 'string', ), - 'btn-primary-hover-text' => array( + 'btn-primary-hover-color' => array( 'type' => 'string', ), 'btn-secondary-bg' => array( 'type' => 'string', ), - 'btn-secondary-text' => array( + 'btn-secondary-color' => array( 'type' => 'string', ), 'btn-secondary-hover-bg' => array( 'type' => 'string', ), - 'btn-secondary-hover-text' => array( + 'btn-secondary-hover-color' => array( 'type' => 'string', ), - 'toggle-bg-off' => array( + 'toggle-off-bg' => array( 'type' => 'string', ), - 'toggle-bg-on' => array( + 'toggle-on-knob-bg' => array( 'type' => 'string', ), - 'toggle-bg-readonly' => array( + 'toggle-readonly-bg' => array( 'type' => 'string', ), 'toggle-knob-bg' => array( @@ -632,10 +742,10 @@ private function get_settings_schema(): array { 'cookie-category-block-bg' => array( 'type' => 'string', ), - 'cookie-category-block-bg-hover' => array( + 'cookie-category-block-hover-bg' => array( 'type' => 'string', ), - 'section-border' => array( + 'separator-border-color' => array( 'type' => 'string', ), 'block-text' => array( @@ -667,10 +777,16 @@ private function get_settings_schema(): array { ), ), ), - 'record_consents' => array( + 'consentModalCloseIcon' => array( + 'type' => 'boolean', + ), + 'showConsentModalFooter' => array( 'type' => 'boolean', ), - 'hide_empty_categories' => array( + 'recordConsents' => array( + 'type' => 'boolean', + ), + 'hideEmptyCategories' => array( 'type' => 'boolean', ), 'gcm' => array( @@ -678,8 +794,8 @@ private function get_settings_schema(): array { 'required' => array( 'enabled', 'implementation', - 'ads_data_redaction', - 'url_passthrough', + 'adsDataRedaction', + 'urlPassthrough', 'regions', ), 'properties' => array( @@ -689,10 +805,10 @@ private function get_settings_schema(): array { 'implementation' => array( 'type' => 'string', ), - 'ads_data_redaction' => array( + 'adsDataRedaction' => array( 'type' => 'boolean', ), - 'url_passthrough' => array( + 'urlPassthrough' => array( 'type' => 'boolean', ), 'regions' => array( @@ -728,17 +844,17 @@ private function get_settings_schema(): array { ), ), ), - 'google_tag_gateway' => array( + 'googleTagGateway' => array( 'type' => 'object', 'required' => array( - 'proxy_enabled', - 'gtag_id', + 'proxyEnabled', + 'gtagId', ), 'properties' => array( - 'proxy_enabled' => array( + 'proxyEnabled' => array( 'type' => 'boolean', ), - 'gtag_id' => array( + 'gtagId' => array( 'type' => 'string', ), ), @@ -762,8 +878,8 @@ private function are_cookie_tables_changed( array $prev_settings, array $new_set return true; } - $prev_cookie_table = $prev_settings['pressidium_options']['cookie_table']; - $new_cookie_table = $new_settings['pressidium_options']['cookie_table']; + $prev_cookie_table = $prev_settings['pressidiumOptions']['cookieTable']; + $new_cookie_table = $new_settings['pressidiumOptions']['cookieTable']; $cookie_categories = array( 'necessary', 'analytics', 'targeting', 'preferences' ); @@ -804,8 +920,8 @@ private function maybe_increment_revision( array $new_settings ): int { private function maybe_flush_rewrite_rules( array $new_settings ): void { $prev_settings = Emoji::decode_array( $this->settings->get() ); - $prev_tag_gateway_proxy_enabled = $prev_settings['pressidium_options']['google_tag_gateway']['proxy_enabled'] ?? false; - $new_tag_gateway_proxy_enabled = $new_settings['pressidium_options']['google_tag_gateway']['proxy_enabled'] ?? false; + $prev_tag_gateway_proxy_enabled = $prev_settings['pressidiumOptions']['googleTagGateway']['proxyEnabled'] ?? false; + $new_tag_gateway_proxy_enabled = $new_settings['pressidiumOptions']['googleTagGateway']['proxyEnabled'] ?? false; if ( $prev_tag_gateway_proxy_enabled !== $new_tag_gateway_proxy_enabled ) { flush_rewrite_rules(); @@ -1029,9 +1145,22 @@ public function delete_logs( WP_REST_Request $request ) { * @return WP_Error|WP_REST_Response */ public function update_consent( WP_REST_Request $request ) { + $ip_address = apply_filters( + 'pressidium_cookie_consent_rate_limit_ip_address', + $_SERVER['REMOTE_ADDR'] ?? '' + ); + + if ( $this->rate_limiter->is_throttled( $ip_address ) ) { + return new WP_Error( + 'too_many_requests', + __( 'Too many requests. Please try again later.', 'pressidium-cookie-consent' ), + array( 'status' => 429 ) + ); + } + $settings = $this->settings->get(); - if ( ! $settings['pressidium_options']['record_consents'] ) { + if ( ! $settings['pressidiumOptions']['recordConsents'] ) { $this->logger->warning( 'Attempted to update a consent record while recording was disabled' ); return new WP_Error( diff --git a/includes/Admin/Settings/Settings_Page.php b/includes/Admin/Settings/Settings_Page.php index ff5321e..c9e3956 100644 --- a/includes/Admin/Settings/Settings_Page.php +++ b/includes/Admin/Settings/Settings_Page.php @@ -16,6 +16,7 @@ use const Pressidium\WP\CookieConsent\PLUGIN_DIR; use const Pressidium\WP\CookieConsent\PLUGIN_URL; +use const Pressidium\WP\CookieConsent\PLUGIN_FILE; use const Pressidium\WP\CookieConsent\VERSION; if ( ! defined( 'ABSPATH' ) ) { @@ -124,11 +125,11 @@ private function is_settings_page(): bool { } /** - * Enqueue script(s). + * Enqueue scripts for the settings page. * * @return void */ - public function enqueue_scripts() { + private function enqueue_scripts() { if ( ! $this->is_settings_page() ) { // Not the settings page, bail early return; @@ -167,14 +168,25 @@ public function enqueue_scripts() { array( 'domain' => WP_Utils::get_domain(), 'assets' => array( - 'gtm_template_url' => esc_url( PLUGIN_URL . 'assets/templates/template.tpl' ), - 'screenshots' => array( + 'gtm_template_url' => esc_url( PLUGIN_URL . 'assets/templates/template.tpl' ), + 'screenshots' => array( 'gallery' => esc_url( PLUGIN_URL . 'assets/images/gtm-gallery.png' ), 'import' => esc_url( PLUGIN_URL . 'assets/images/gtm-import.png' ), 'tag' => esc_url( PLUGIN_URL . 'assets/images/gtm-tag.png' ), 'config' => esc_url( PLUGIN_URL . 'assets/images/gtm-config.png' ), ), - 'promo' => esc_url( PLUGIN_URL . 'assets/images/promo.png' ), + 'promo' => esc_url( PLUGIN_URL . 'assets/images/promo.png' ), + 'performanceBanner' => esc_url( PLUGIN_URL . 'assets/images/performance-banner.png' ), + ), + 'urls' => array( + 'performance_plugin_search' => add_query_arg( + array( + 's' => rawurlencode( 'Pressidium Performance' ), + 'tab' => 'search', + 'type' => 'term', + ), + admin_url( 'plugin-install.php' ) + ), ), 'api' => array( 'route' => 'pressidium-cookie-consent/v1/settings', @@ -199,6 +211,39 @@ public function enqueue_scripts() { ); } + /** + * Enqueue styles for the installed plugin pages. + * + * @param string $hook The current admin page. + * + * @return void + */ + private function enqueue_styles( string $hook ): void { + if ( $hook !== 'plugins.php' ) { + // Not on the plugins page, bail early + return; + } + + wp_enqueue_style( + 'pressidium-cookie-consent-installed-plugins', + PLUGIN_URL . 'assets/css/admin-styles.css', + array(), // no dependencies + VERSION + ); + } + + /** + * Enqueue any scripts and styled needed for the admin pages. + * + * @param string $hook The current admin page. + * + * @return void + */ + public function admin_enqueue_scripts_and_styles( string $hook ): void { + $this->enqueue_scripts(); + $this->enqueue_styles( $hook ); + } + /** * Add information about this plugin to the left side of the admin footer. * @@ -233,7 +278,7 @@ public function admin_footer_info( ?string $content ): ?string { } /** - * Add plugin version to the right side of the admin footer. + * Add the plugin version to the right side of the admin footer. * * @param string|null $content The existing content. * @@ -252,6 +297,45 @@ public function admin_footer_version( ?string $content ): ?string { ); } + /** + * Filter the action links displayed for this plugin to add links to its settings page and documentation. + * + * @link https://developer.wordpress.org/reference/hooks/plugin_action_links/ + * + * @param string[] $actions An array of plugin action links. + * @param string $plugin_file Path to the plugin file relative to the `plugins` directory. + * + * @return string[] Plugin action links including the settings and documentation links. + */ + public function add_plugin_links( array $actions, string $plugin_file ): array { + if ( plugin_basename( PLUGIN_FILE ) !== $plugin_file ) { + return $actions; + } + + $settings_page_url = add_query_arg( + array( 'page' => $this->get_menu_slug() ), + admin_url( 'admin.php' ) + ); + + $documentation_url = 'https://github.com/pressidium/pressidium-cookie-consent/wiki'; + + $actions['settings'] = sprintf( + '%2$s', + esc_url( $settings_page_url ), + esc_html__( 'Settings', 'pressidium-cookie-consent' ), + ); + + $actions['documentation'] = sprintf( + '%2$s%3$s', + esc_url( $documentation_url ), + esc_html__( 'Docs', 'pressidium-cookie-consent' ), + /* translators: Accessibility text. */ + esc_html__( '(opens in a new tab)', 'pressidium-cookie-consent' ) + ); + + return $actions; + } + /** * Return the actions to register. * @@ -260,7 +344,7 @@ public function admin_footer_version( ?string $content ): ?string { public function get_actions(): array { $actions = parent::get_actions(); - $actions['admin_enqueue_scripts'] = array( 'enqueue_scripts' ); + $actions['admin_enqueue_scripts'] = array( 'admin_enqueue_scripts_and_styles' ); return $actions; } @@ -272,8 +356,9 @@ public function get_actions(): array { */ public function get_filters(): array { return array( - 'admin_footer_text' => array( 'admin_footer_info' ), - 'update_footer' => array( 'admin_footer_version', 11 ), + 'admin_footer_text' => array( 'admin_footer_info' ), + 'update_footer' => array( 'admin_footer_version', 11 ), + 'plugin_action_links' => array( 'add_plugin_links', 10, 2 ), ); } diff --git a/includes/Client/Consent_Mode.php b/includes/Client/Consent_Mode.php index a46e03e..c24fac2 100644 --- a/includes/Client/Consent_Mode.php +++ b/includes/Client/Consent_Mode.php @@ -78,7 +78,7 @@ public function early_enqueue_scripts(): void { 'pressidiumCCGCM', array( // This needs to be nested so our boolean values are not converted to strings - 'gcm' => $this->settings['pressidium_options']['gcm'] ?? array(), + 'gcm' => $this->settings['pressidiumOptions']['gcm'] ?? array(), ), ); } diff --git a/includes/Client/Cookie_Consent.php b/includes/Client/Cookie_Consent.php index 5678151..d349d64 100644 --- a/includes/Client/Cookie_Consent.php +++ b/includes/Client/Cookie_Consent.php @@ -54,29 +54,64 @@ private function get_settings(): array { */ $cc_settings = array_merge( array(), $this->settings ); - $category_blocks_map = array( + $category_sections_map = array( 'necessary' => 1, 'analytics' => 2, 'targeting' => 3, 'preferences' => 4, ); - $primary_btn_role = $cc_settings['pressidium_options']['primary_btn_role']; - $secondary_btn_role = $cc_settings['pressidium_options']['secondary_btn_role']; + $consent_modal_close_icon = $cc_settings['pressidiumOptions']['consentModalCloseIcon'] ?? true; - foreach ( $cc_settings['languages'] as $language => $language_settings ) { - foreach ( $category_blocks_map as $category => $index ) { - $table = $cc_settings['pressidium_options']['cookie_table'][ $category ]; + $show_footer = $cc_settings['pressidiumOptions']['showConsentModalFooter'] ?? true; - $cc_settings['languages'][ $language ]['settings_modal']['blocks'][ $index ]['cookie_table'] = $table; + foreach ( $cc_settings['language']['translations'] as $language => $language_settings ) { + $cc_settings['language']['translations'][ $language ]['consentModal']['closeIconLabel'] = $consent_modal_close_icon ? 'Close' : null; + $cc_settings['language']['translations'][ $language ]['preferencesModal']['closeIconLabel'] = 'Close'; - if ( empty( $table ) ) { - unset( $cc_settings['languages'][ $language ]['settings_modal']['blocks'][ $index ]['cookie_table'] ); + if ( ! $show_footer ) { + $cc_settings['language']['translations'][ $language ]['consentModal']['footer'] = ''; + } else { + $footer_links = $language_settings['consentModal']['footerLinks'] ?? array(); + $footer_html = ''; + + foreach ( $footer_links as $link ) { + $url = trim( $link['url'] ?? '' ); + $label = trim( $link['label'] ?? '' ); + + if ( empty( $url ) || empty( $label ) ) { + continue; + } + + $footer_html .= sprintf( + '%s', + esc_url( $url ), + esc_html( $label ) + ); } + + $cc_settings['language']['translations'][ $language ]['consentModal']['footer'] = $footer_html; } - $cc_settings['languages'][ $language ]['consent_modal']['primary_btn']['role'] = $primary_btn_role; - $cc_settings['languages'][ $language ]['consent_modal']['secondary_btn']['role'] = $secondary_btn_role; + unset( $cc_settings['language']['translations'][ $language ]['consentModal']['footerLinks'] ); + + foreach ( $category_sections_map as $category => $index ) { + $body = $cc_settings['pressidiumOptions']['cookieTable'][ $category ]; + + if ( empty( $body ) ) { + unset( $cc_settings['language']['translations'][ $language ]['preferencesModal']['sections'][ $index ]['cookieTable'] ); + continue; + } + + $headers = $cc_settings['pressidiumOptions']['cookieTableHeaders']['translations'][ $language ] + ?? $cc_settings['pressidiumOptions']['cookieTableHeaders']['translations']['en'] + ?? array(); + + $cc_settings['language']['translations'][ $language ]['preferencesModal']['sections'][ $index ]['cookieTable'] = array( + 'headers' => $headers, + 'body' => $body, + ); + } } if ( ! $cc_settings['reconsent'] ) { @@ -84,7 +119,7 @@ private function get_settings(): array { } unset( $cc_settings['reconsent'] ); - unset( $cc_settings['pressidium_options'] ); + unset( $cc_settings['pressidiumOptions'] ); return $cc_settings; } @@ -131,9 +166,9 @@ public function enqueue_scripts(): void { 'cookie-consent-client-script', 'pressidiumCCClientDetails', array( - 'settings' => $this->get_settings(), - 'api' => array( - 'rest_url' => rest_url(), + 'settings' => $this->get_settings(), + 'api' => array( + 'rest_url' => rest_url(), 'route' => 'pressidium-cookie-consent/v1/settings', 'consent_route' => 'pressidium-cookie-consent/v1/consent', 'consents_route' => 'pressidium-cookie-consent/v1/consents', @@ -145,10 +180,10 @@ public function enqueue_scripts(): void { * of our boolean values. */ 'additional_options' => array( - 'record_consents' => boolval( $this->settings['pressidium_options']['record_consents'] ?? true ), - 'hide_empty_categories' => boolval( $this->settings['pressidium_options']['hide_empty_categories'] ?? false ), - 'floating_button' => $this->settings['pressidium_options']['floating_button'] ?? array(), - 'gcm' => $this->settings['pressidium_options']['gcm'] ?? array(), + 'recordConsents' => boolval( $this->settings['pressidiumOptions']['recordConsents'] ?? true ), + 'hideEmptyCategories' => boolval( $this->settings['pressidiumOptions']['hideEmptyCategories'] ?? false ), + 'floatingButton' => $this->settings['pressidiumOptions']['floatingButton'] ?? array(), + 'gcm' => $this->settings['pressidiumOptions']['gcm'] ?? array(), ), ) ); @@ -176,8 +211,8 @@ public function admin_enqueue_scripts( string $hook_suffix ): void { * @return void */ private function print_inline_script(): void { - if ( ! $this->settings['page_scripts'] || empty( $this->settings['pressidium_options']['blocked_scripts'] ) ) { - // Either "Page scripts" are disabled, or there are no blocked scripts, bail early + if ( ! $this->settings['manageScriptTags'] || empty( $this->settings['pressidiumOptions']['blockedScripts'] ) ) { + // Either "Manage script tags" is disabled, or there are no blocked scripts, bail early return; } @@ -192,8 +227,8 @@ private function print_inline_script(): void { ?> @@ -207,7 +242,7 @@ private function print_inline_script(): void { * @return void */ private function print_consent_mode_inline_script(): void { - if ( ! $this->settings['pressidium_options']['gcm']['enabled'] ) { + if ( ! $this->settings['pressidiumOptions']['gcm']['enabled'] ) { // GCM is not enabled, bail early return; } @@ -240,16 +275,15 @@ private function print_inline_style(): void {