توضیحات
ONiDEA Consenso Cookie Conforme Italia is a free, self-hosted alternative to subscription services like CookieYes or Cookiebot, covering the essential cookie consent features for WordPress sites:
- Consent banner with “Accept all” / “Reject all” buttons of equal visual prominence (as required by the Italian Data Protection Authority’s — Garante Privacy — guidelines) plus a “Customize” option.
- Preferences panel with categories: Necessary (always on), Statistics, Marketing, Functional — enabled individually per site.
- Automatic blocking of scripts marked as non-essential until the user gives consent.
- Google Consent Mode v2: sets consent signals for Google Analytics 4 / Google Ads / AdSense before their scripts load, so they automatically honor the user’s choice (only needs enabling where relevant).
- Meta (Facebook) Pixel built in: enter the pixel ID in Settings and it is printed as a blocked script, loaded only after the visitor accepts the chosen category (PageView, plus optional WooCommerce events; production environment only; never for administrators).
- Server-side consent log (date, chosen categories, page, hashed IP — never stored in the clear) for the accountability record required by the GDPR, with CSV export.
- Italian by default, with a one-click English preset for the banner texts (Settings page) for sites that also serve an English-speaking audience.
- Engine built on the open-source “CookieConsent” library by Orest Bida (MIT license), served from your own site: no third-party calls, no subscription fee.
What it does NOT do (unlike paid services)
- No automatic recurring scan of the site’s cookies: categories and the scripts to block are configured manually (see the quick-start guide, in Italian).
- Not an IAB TCF-certified CMP: suited to Google Ads and GA4 (via Consent Mode, which has no CMP-certification requirement) and to the general run of editorial/business/e-commerce sites. For Google AdSense specifically, note that since 16 January 2024 Google requires a certified CMP integrated with the IAB TCF to serve personalized ads in the EEA/UK — without one, AdSense falls back to non-personalized/limited ads there (lower revenue, not no ads). This plugin does not meet that certification, so AdSense sites in the EEA/UK should weigh that trade-off, or pair it with a certified CMP for the ad-consent piece specifically. Not suited either way to publishers selling inventory through multiple ad exchanges/SSPs that require full IAB certification.
- Does not provide legal privacy/cookie policy text: that remains your responsibility or your legal counsel’s.
Included features
Every feature of the plugin — banner, categories, script blocking, Google Consent Mode v2, proof-of-consent log with CSV export, and the Dashboard with consent reporting/trends (accepted/rejected/partial breakdown, last-7-days chart) — is included and active for anyone who installs the plugin, with no distinctions. The “Powered by ONiDEA adv” credit at the bottom of the banner is disabled by default and can be turned on by anyone from Settings.
Any future premium extensions (if and when they arrive) will be a separate, independently distributed add-on — never functionality hidden inside this same package.
Credits and licenses
The banner engine is the open-source CookieConsent library by Orest Bida (https://github.com/orestbida/cookieconsent), released under the MIT license — fully compatible with this plugin’s GPLv2+ license. assets/js/cookieconsent.umd.js is the library’s own build file, unmodified. Its CSS is unmodified in substance but split into two files, assets/css/cookieconsent.css and assets/css/cookieconsent-preferences.css, so the ~41% belonging only to the preferences panel can be loaded on demand instead of on every page (see enqueue_assets()); no rule was changed in the process. The original MIT license text is available at the repository above.
Plugin developed and maintained by ONiDEA adv, a web agency based in Milan, Italy.
عکسهای صفحه




نصب
- Upload the
onidea-cookie-consentfolder to/wp-content/plugins/. - Activate the plugin from the WordPress Plugins screen.
- In the admin sidebar, open “Consenso Cookie” and configure categories, banner text, and links to your privacy/cookie policy (under the “Settings” entry of the new menu).
- If the site uses AdSense/Google Ads/GA4, enable “Google Consent Mode”.
- See the quick-start guide (Italian) for how to tag third-party scripts that need blocking.
سوالات متداول
-
Why doesn’t the REST endpoint that logs consent use a nonce?
-
Deliberate choice, not an oversight. A WordPress nonce is generated when the page is rendered: on a site with page caching (practically all of them, in production) it ends up baked into the cached HTML and is replayed identically by every visitor for as long as that cache lives — often longer than the nonce’s own lifetime. The practical result, observed during development: consents silently rejected by the endpoint (a
200response with{"logged":false}, no visible error) for the entire lifetime of the cache.A nonce, in this specific case, does not protect anything worth protecting: the route is public by design (
permission_callbackis__return_true, deliberately — it must be callable by an anonymous visitor who has no account yet), it doesn’t write anything privileged (only a row in an accountability-only log), and for a logged-out visitor the token is identical for everyone anyway. In its place: strict per-argument validation (type, length, and a category whitelist, so only well-formed rows can ever be written), a same-origin check on the request, and a 20-calls-per-hour-per-IP limit against abuse — computed fromREMOTE_ADDRonly by default, since request headers likeX-Forwarded-Forare attacker-controllable and are not trusted unless a site explicitly opts in via theoccit_trust_proxy_ip_headersfilter (for sites that know they sit behind a proxy/CDN they control). None of this is a substitute for authentication; it bounds the worst case to “some extra rows in a low-sensitivity accountability log,” which is the actual risk on this endpoint. Details in the code, inclass-occ-frontend.phpand the REST handler. -
Does the plugin send data to external services?
-
No. The banner engine (the “CookieConsent” library by Orest Bida) is downloaded once during development and distributed inside the plugin itself: it runs entirely on your own site, with no call to any third-party service either at runtime or during configuration. The consent log is a table in your own database.
-
How do I tag a third-party script so it’s blocked until consent?
-
Add two attributes to its
<script>tag:type="text/plain"(in place oftext/javascript) anddata-category="analytics"(ormarketing/functional, matching the category it belongs to). The script only runs once the visitor accepts that category. The quick-start guide (Italian) walks through this with examples, where to find scripts to edit, and how to verify it worked. Google Analytics/Ads/AdSense need no tagging: enable Google Consent Mode instead.
نقد و بررسیها
نقد و بررسیای برای این افزونه یافت نشد.
توسعه دهندگان و همکاران
“ONiDEA Consenso Cookie Conforme Italia” نرم افزار متن باز است. افراد زیر در این افزونه مشارکت کردهاند.
مشارکت کنندگانترجمه “ONiDEA Consenso Cookie Conforme Italia” به زبان شما.
علاقه مند به توسعه هستید؟
کد را مرور کنید، مخزن SVN را بررسی کنید، یا از طریق RSS در گزارش توسعه مشترک شوید.
گزارش تغییرات
1.10.4
New — consents per page in the Dashboard. The “Pagine con più consensi” panel is replaced by a “Consensi per pagina” table (last 30 days, top 10): for each page it shows total, accepted all, partial and rejected consents and the rejection rate. Addresses are grouped by path, without query strings (UTM and similar), and the table can be sorted by volume or by rejection rate (pages with at least 5 consents). No settings or stored data change.
1.10.3
New — more consent statistics in the Dashboard. A new “Consensi per periodo” table shows today, yesterday, the last 7 days and the last 30 days (total, accepted all, partial, rejected, acceptance rate), plus a comparison with the previous 7 days. Two new panels show opt-in rate per category and the pages with the most consents (last 30 days). Dates follow the site’s timezone. No settings or stored data change.
1.10.2
Change — the “Privacy e conformità” settings tab is split into sub-tabs: Google Consent Mode v2, Pixel di Meta, Eventi e-commerce, and Link e registro (legal links, consent duration, consent log). Only the layout changes: every field is still in the same form and saved exactly as before. With JavaScript disabled all sections show at once, as before. The last sub-tab you used is remembered in your browser.
1.10.1
New — AddToCart event, and a private order note for Purchase.
- AddToCart is queued on the server whenever something is added to the cart (classic form, AJAX button, block cart, third-party widgets) — only if the visitor has already consented — and delivered to the pixel right after an AJAX add, or on the next page otherwise. The price is the real cart line price (extra options included), the quantity is the quantity added by that action.
- When a Purchase event is prepared for the browser with marketing consent present, a private note is added to the WooCommerce order (“Pixel Meta: evento Purchase predisposto…”), so the shop can see in wp-admin that the event went out.
- New REST route
occit/v1/meta-events/drain(public, POST): returns and clears only the caller’s own queued AddToCart events. - Excluded roles and the logged-in exclusion now apply to AJAX add-to-cart too.
1.10.0
New — WooCommerce events for the built-in Meta pixel (off by default). Settings > Privacy e conformità > “Eventi e-commerce”: ViewContent on product pages, InitiateCheckout on the checkout (classic and block checkout), Purchase on the order-received page. Like the base pixel they are inert type="text/plain" scripts tagged with the pixel’s consent category: nothing is sent before consent.
- Purchase is sent once per order, only for orders in “Processing” or “Completed” status created in the last 24 hours, and only when the order key in the URL matches. The event id is saved on the order (
_occit_purchase_event_id) for a future Conversions API call. - Product ids: product/variation ID or SKU, with an optional prefix, so they can match a Meta catalog. Value is computed from order lines after discounts, with taxes and shipping included or not per setting; currency comes from the order.
- New “Ruoli esclusi” setting: roles that are never tracked (administrators were already excluded).
- The events cannot be switched on while PixelYourSite, Facebook for WooCommerce, Meta pixel for WordPress or Pixel Caffeine is active, to avoid duplicate events. A pixel added by hand or through Google Tag Manager cannot be detected.
- Declares compatibility with WooCommerce High-Performance Order Storage.
1.9.0
New — built-in Meta (Facebook) Pixel, loaded only after consent. Settings > Privacy e conformità has a new “Pixel di Meta (Facebook)” section: enable it, paste the pixel ID and pick the consent category (default: the same as the advertising category, normally Marketing). The pixel is printed in the page head as an inert type="text/plain" script tagged with that category, so the banner engine downloads and runs it only after the visitor accepts it. Meta has no equivalent of Google’s Consent Mode, so not loading the script at all is the only correct approach. No pixel ID is hard-coded: each site configures its own.
- Only the
PageViewevent is sent. No Advanced Matching and no Conversions API. - No
<noscript><img>fallback on purpose: that image would contact facebook.com regardless of consent. - The pixel is printed only when the WordPress environment type is
production(setWP_ENVIRONMENT_TYPEin wp-config.php on local and staging copies), never for users who can manage options, never on admin, AJAX, feed, preview or customizer requests. An optional checkbox also excludes every logged-in user. - The ID must be 15-16 digits; otherwise a notice is shown and nothing is printed. A notice also appears if the chosen category is not active on the site.
- If the pixel is tied to a category other than Marketing, its
_fbp/_fbccookies are cleared when that category is revoked (for Marketing this already happened). - Remember to list
_fbpand_fbc(Meta Platforms Ireland, 3 months) in your cookie policy and to name Meta in your privacy policy.
1.8.4
Fix — the new text fields added in 1.8.3 showed up empty on any site that had already saved its settings. get_settings() merges saved values over the defaults with wp_parse_args(), which only merges top-level keys; once a site has a texts array saved at all (true for every site past its first save), that whole array was kept exactly as saved, so a text key introduced later (like 1.8.3’s close_label/cookie_policy_notice/cookie_policy_link) stayed blank instead of falling back to its Italian default — confirmed live on a real, already-configured install while verifying 1.8.3. The texts array is now merged against its own defaults specifically, so newly-added text fields appear with their default wording immediately, no re-save required.
1.8.3
New — the English preset now covers the whole banner, not just the visible form fields. Two strings were previously hardcoded in Italian regardless of the chosen preset: the preferences panel’s close-icon label (“Chiudi”) and the “see our cookie policy” line shown under the categories. Both are now editable text fields (Settings > Testi) with their own English preset values, so switching to English no longer leaves two Italian sentences behind.
Fix — “Messaggio pannello preferenze” had no effect. The field has existed since before this release, but the banner engine never actually read it — it was saved and displayed in Settings, with nothing downstream using it. It now shows as an intro paragraph at the top of the preferences panel, above the category list.
Fix — “Impostazioni salvate” never appeared. A successful save redirects back with ?settings-updated=1, but the Settings page never turned that into a visible message — only the (rare) contrast warnings ever showed up in that spot, so every ordinary save looked like it silently did nothing. A confirmation now shows there too.
Accuracy — the “not IAB TCF certified” note undersold what that means for Google AdSense specifically. It read as a niche caveat about programmatic ad exchanges. Since 16 January 2024, Google requires a certified CMP integrated with the IAB TCF for personalized AdSense ads in the EEA/UK specifically — a much more common case than “selling inventory through multiple SSPs”. The readme (and the matching section on the plugin’s marketing page) now say so plainly: AdSense without a certified CMP falls back to non-personalized/limited ads there, not to a full loss of ads, but a real trade-off worth knowing before choosing this plugin for an AdSense-funded site.
Cleanup — no functional change. Notice-box styling in the Settings page’s “Categorie e script” tab moved from inline style attributes to an enqueued stylesheet (occit-admin-settings.css), matching wordpress.org’s guideline against inline <style>/style="" in admin views already followed elsewhere in this plugin. The sub-tabs (Categorie e script / Testi / Aspetto / Privacy e conformità) now carry proper ARIA tab/tabpanel roles for assistive tech. A couple of local view variables were renamed to match this codebase’s naming convention. The credits section’s claim that the bundled CookieConsent library is “unmodified” now correctly notes that its CSS is split into two files (unchanged in substance) so the preferences-panel styles can load on demand.
1.8.2
Fix — “Salva impostazioni” could silently do nothing. Two number fields (cookie duration, cookie-policy revision) live on the “Privacy e conformità” tab and use the browser’s native validation (min="1"). If one of them held an invalid value (e.g. left empty, saved as 0) while a different tab was showing, the browser correctly blocked the submission but couldn’t show its native error bubble on a hidden, unfocusable field — so clicking Save appeared to do nothing, with no visible explanation. Fixed two ways: the JS now switches to the tab containing the invalid field before the browser tries to show its error, and the revision number can no longer be saved as 0 (floored to 1, matching the existing floor on the cookie-duration field).
Fix — inaccurate claim in the Google Analytics/Ads/AdSense callout (added in 1.8.1). The box said Google Consent Mode “blocks/unblocks” these scripts automatically. In reality Consent Mode never blocks the script from loading — it only tells Google the user’s consent status (the analytics_storage/ad_storage signals), and only once the matching category (Statistiche or Marketing) is active for the site; without that category enabled, consent stays denied regardless of Consent Mode. The callout now describes this accurately.
1.8.1
Clarity — the “no manual tagging for Google Analytics/Ads/AdSense” note is now its own warning box. On the “Categorie e script” tab, that exception was previously a trailing sentence at the end of a longer paragraph about manual script tagging and was easy to miss. It’s now a separate, highlighted callout right below the tagging instructions, making clear that Google Analytics, Google Ads and AdSense should not be tagged by hand — Google Consent Mode (Privacy e conformità tab) already handles them. No functional change.
1.8.0
New — Settings page reorganized into tabs. With the new language preset (below) the Settings page had grown to nine sections under one long scroll. It’s now four tabs — Categorie e script, Testi, Aspetto, Privacy e conformità — switched client-side with no page reload; every field stays in the form and in the saved request regardless of which tab is showing, so nothing resets on save. The last tab you had open is remembered (localStorage) for your next visit. If JavaScript is disabled, all sections simply show at once, exactly as before this change — nothing breaks or disappears.
Fix — the “Rifiuta tutti” contrast warning never actually showed. Since 1.7.0, saving a custom reject-button color with contrast between 3:1 and 4.5:1 was meant to show an admin warning (and below 3:1, revert the style with an explanation) — but the settings page never called settings_errors(), so neither notice was ever displayed; the revert itself still happened silently. Both notices now show correctly at the top of the Settings page after saving.
New — English preset for the banner texts. The plugin targets Italian sites, so every text still defaults to Italian. On the Settings page’s “Testi” tab, a new “Lingua dei testi” section lets you pick Italian or English and fill in the banner title, buttons, preferences panel and category labels in one click. It only fills the existing form fields — nothing is saved until you review the result and click “Salva impostazioni” — so any wording you already customized is never overwritten silently. Useful for sites with an English-facing version; it does not add automatic per-visitor language switching (for that, a full multilingual setup with WPML/Polylang remains the right tool).
1.7.1
Documentation only. The plugin folder no longer ships GUIDA-RAPIDA.md (removed from the distributed package since 1.5.2, per wordpress.org’s Plugin Check), but this readme and the “Next steps” list on the Settings page still pointed to it, leaving users with a dead reference and no way to find the script-tagging instructions. Both now link to an online quick-start guide instead, and the Settings page also gets a dedicated help box on tagging scripts, next to the category checkboxes. No functional change.
1.7.0
Fix — the preferences panel flashed and did not open on the first click. The panel’s stylesheet is fetched on demand, and two things went wrong before it arrived: the unstyled panel markup could be painted into the page, and the “panel is visible” rule depends on a .cc--anim class the library only adds 100 ms after creating the panel (measured 360-420 ms on a busy page), so the first open was invisible for that whole window. The banner stylesheet now carries a small always-present rule that keeps the panel out of sight until its own stylesheet applies, and the panel no longer waits for that timer on its first open.
New — optional styling for the “Reject all” button (off by default). Under Appearance you can now give the reject button its own colours: a filled custom colour, or an outline. Only colours change: size, font weight, padding and position stay identical to “Accept all”, so the button can never be shrunk or demoted from these settings. Contrast is measured on save — below 3:1 the style is not applied at all and the button stays identical to “Accept all”, between 3:1 and 4.5:1 it is saved with a warning. The default remains two identical buttons, which is what the Italian DPA’s 2021 cookie guidelines assume.
1.6.2
Second round of wordpress.org review fixes. The tools/ folder (developer-only scripts, .py/.mjs, not needed at runtime) is no longer included in the distributed package — it stays in the source repository for internal use. Hardened the unauthenticated consent-log REST endpoint: added strict per-argument validation (type, length, a whitelist of the four known category keys) so the log table can only ever receive well-formed rows, and the per-IP rate limit now reads only REMOTE_ADDR by default instead of also trusting the attacker-controllable X-Forwarded-For/CF-Connecting-IP headers (opt-in via the new occit_trust_proxy_ip_headers filter for sites that know they sit behind a trusted proxy/CDN). The endpoint remains intentionally public (no user account exists to authenticate against) — see the FAQ below for the full rationale. No visible change for site visitors.
1.6.1
Updated the “Tested up to” header to 7.1, per wordpress.org’s automated submission scan (the previous 7.0 value was flagged as outdated). No functional change.
1.6.0
Renamed the plugin to “ONiDEA Consenso Cookie Conforme Italia” (previously “Consenso Cookie Conforme Italia”), per wordpress.org directory guideline 17 (distinctive naming) — the previous name was too close to the generic pattern used by many other cookie-consent plugins. Internal function/class/option/hook names were also renamed from the “occ_” prefix (3 characters) to “occit_”, meeting the directory’s minimum prefix length; existing settings and the consent-log table are migrated automatically and transparently on upgrade, no data is lost. The Dashboard page’s CSS moved from an inline <style> block to a properly enqueued stylesheet. No visible change for site visitors; wp-admin menu URLs change (occ-dashboard occit-dashboard, etc.) and any old bookmarks to them will need updating.
1.5.5
Text Domain header updated to match the wordpress.org-assigned slug (consenso-cookie-conforme-italia), fixing a textdomain_mismatch warning raised by the automated submission scan. No functional change.
1.5.4
Removed the Plugin URI header (it was identical to the Author URI, which wordpress.org’s submission form does not allow — the two must point to different pages). Kept the Author URI pointing to the agency site, since there is no dedicated page for this specific plugin yet. No functional change.
1.5.3
Translated readme.txt into English, per wordpress.org’s directory-listing language policy (July 2025): the readme is now the base language for community translations via translate.wordpress.org. The plugin itself — admin screens, banner text, settings, GUIDA-RAPIDA.md — remains entirely in Italian, as intended for its target audience. No functional change.
1.5.2
Fixed the findings from wordpress.org’s official Plugin Check: prepared direct database queries are now documented with the matching phpcs exemption instead of being left unannotated; the CSV export’s write to php://output (the HTTP response stream, not a real file — WP_Filesystem doesn’t apply here) is documented the same way; removed GUIDA-RAPIDA.md from the distributed package (an internal guide for the agency, not required for the plugin to work — still available in the source repository). No functional change for site visitors.
1.5.1
Added a reference to the agency’s site (ONiDEA adv, web agency in Milan) in the plugin header (Plugin URI/Author URI) and in the readme’s Credits section. No functional change for site visitors.
1.5.0
Removed the Free/Pro distinction: the Dashboard with consent reporting and trends, previously reserved for the Pro tier, is now included and active for everyone. The wordpress.org directory guidelines (guideline 5, “trialware”) do not allow functionality that already exists in the code but is disabled behind a license flag — this removal brings the plugin in line with that requirement ahead of submission. Any future premium extensions will be a separate add-on, never a hidden switch inside this same package.
1.4.1
Renamed the plugin to “Consenso Cookie Conforme Italia” (previously “Cookie Consent – by ONiDEA”), ahead of a future submission to the official wordpress.org repository — the previous name remains as the author/agency name, no longer as the plugin name. No change to how the plugin behaves for site visitors. Internal cleanup: code brought in line with the WordPress Coding Standards (complete docblocks, style conventions), added an FAQ section (justification for the log endpoint’s nonce-free design, confirmation of no calls to external services), a Credits and licenses section for the bundled CookieConsent library, and a Screenshots section.
1.4.0
The “Powered by ONiDEA adv” credit is now disabled by default at every tier (previously always on in Free, only removable in Pro) and is a free-standing Settings option independent of tier. Also fixed the “|” divider between the banner footer links, which stayed stuck to the first link when only two remained (e.g. Privacy Policy and Cookie Policy with the credit off): spacing is now symmetric regardless of how many links are present.
1.3.2
The “Manage cookie preferences” button now works even where wp_kses_post() strips its inline onclick — i.e. in widgets, filtered content, and many theme templates, where it used to stay visible but inert. The click is now captured via delegation in occ-init.js, so the button no longer depends on an inline attribute (also useful under a Content-Security-Policy).
1.3.1
The banner’s two JavaScript files now load with defer. Without it, they blocked the parser and the browser fetched them at high priority, taking bandwidth away from the render-blocking CSS: the banner can never appear before the page itself, so that priority bought nothing and cost something.
1.3.0
The preferences-panel stylesheet (roughly 41% of the library’s CSS) is no longer loaded with the page: it’s only fetched by visitors who actually open the panel. Everyone else never downloads it. The split is regenerated with tools/split-modal-css.py after a library update.
1.2.0
Banner settings now travel in a <script type="application/json"> block instead of via wp_localize_script: optimization plugins that combine JavaScript also swallow inline scripts, so excluding the banner script from the bundle (to make it appear earlier) left it without its settings and the banner failed to appear at all.
The consent log no longer requires a nonce: it used to get baked into the HTML when the page cache was written and expired before that cache did, silently losing consents on every cached site. In its place: a same-origin check and a per-IP hourly limit.
1.1.0
Added the “Powered by ONiDEA adv” credit to the banner (removable in the Pro version) and a Free/Pro distinction (dashboard reporting reserved for the Pro version).
1.0.0
First release.
