{"id":394664,"date":"2026-10-31T18:55:02","date_gmt":"2026-10-31T18:55:02","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/mammothwp-acceptance-logs\/"},"modified":"2026-10-31T18:54:44","modified_gmt":"2026-10-31T18:54:44","slug":"mammoth-acceptance-logs","status":"publish","type":"plugin","link":"https:\/\/wordpress.org\/plugins\/mammoth-acceptance-logs\/","author":23592418,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.0.0","stable_tag":"1.0.0","tested":"7.1.4","requires":"6.2","requires_php":"8.1","requires_plugins":null,"header_name":"MammothWP Acceptance Logs","header_author":"Mammoth WP","header_description":"Records that your logged-in users accepted your terms. Versioned, role-scoped, tamper-evident acceptance logs with a permanent archive of every version.","assets_banners_color":"c9c5bc","last_updated":"2026-10-31 18:54:44","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/mammothwp.com\/plugins\/mammothwp-acceptance-logs\/","header_author_uri":"https:\/\/mammothwp.com","rating":0,"author_block_rating":0,"active_installs":0,"downloads":562,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.0.0":{"tag":"1.0.0","author":"mammothwp","date":"2026-10-31 18:54:44","revision":3777297}},"upgrade_notice":{"1.0.0":"<p>First public release. Installs coming from earlier internal builds are migrated automatically on first load.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3777297,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3777297,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256},"icon.svg":{"filename":"icon.svg","revision":3777297,"resolution":false,"location":"assets","locale":false}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3777297,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3777297,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":{"mmwp\/terms-display":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"mmwp\/terms-display","version":"1.0.0","title":"Terms & Conditions","description":"Shows the current Terms & Conditions \u2014 version, effective date and summary \u2014 with the full text in a modal.","category":"widgets","icon":"media-text","keywords":["terms","conditions","legal","policy"],"textdomain":"mammoth-acceptance-logs","attributes":{"heading":{"type":"string","default":""},"showHistory":{"type":"boolean","default":true},"historyLimit":{"type":"number","default":10},"buttonLabel":{"type":"string","default":""}},"supports":{"html":false,"align":["wide","full"],"spacing":{"margin":true,"padding":true}},"editorScript":"mmwp-terms-block-editor","viewScript":"file:..\/..\/assets\/js\/terms-block.js","style":"file:..\/..\/assets\/css\/terms-block.css"}},"tagged_versions":["1.0.0"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3777297,"resolution":"1","location":"assets","locale":"","width":1280,"height":1400},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3777297,"resolution":"2","location":"assets","locale":"","width":1280,"height":1179},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3777297,"resolution":"3","location":"assets","locale":"","width":1280,"height":800},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3777297,"resolution":"4","location":"assets","locale":"","width":1280,"height":1124}},"screenshots":{"1":"The Terms &amp; Conditions settings screen, where terms are written and published.","2":"The acceptance log with signature verification.","3":"The acceptance popup shown to users in scope.","4":"The public Terms &amp; Conditions block."}},"plugin_section":[],"plugin_tags":[171668,8534,14361,131785,1901],"plugin_category":[57],"plugin_contributors":[289965],"plugin_business_model":[],"class_list":["post-394664","plugin","type-plugin","status-publish","hentry","plugin_tags-acceptance","plugin_tags-audit-log","plugin_tags-compliance","plugin_tags-gdpr","plugin_tags-terms","plugin_category-taxonomy","plugin_contributors-mammothwp","plugin_committers-mammothwp"],"banners":{"banner":"https:\/\/ps.w.org\/mammoth-acceptance-logs\/assets\/banner-772x250.png?rev=3777297","banner_2x":"https:\/\/ps.w.org\/mammoth-acceptance-logs\/assets\/banner-1544x500.png?rev=3777297","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":"https:\/\/ps.w.org\/mammoth-acceptance-logs\/assets\/icon.svg?rev=3777297","icon":"https:\/\/ps.w.org\/mammoth-acceptance-logs\/assets\/icon.svg?rev=3777297","icon_2x":false,"generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/mammoth-acceptance-logs\/assets\/screenshot-1.png?rev=3777297","caption":"The Terms &amp; Conditions settings screen, where terms are written and published."},{"src":"https:\/\/ps.w.org\/mammoth-acceptance-logs\/assets\/screenshot-2.png?rev=3777297","caption":"The acceptance log with signature verification."},{"src":"https:\/\/ps.w.org\/mammoth-acceptance-logs\/assets\/screenshot-3.png?rev=3777297","caption":"The acceptance popup shown to users in scope."},{"src":"https:\/\/ps.w.org\/mammoth-acceptance-logs\/assets\/screenshot-4.png?rev=3777297","caption":"The public Terms &amp; Conditions block."}],"raw_content":"<!--section=description-->\n<p>MammothWP Acceptance Logs asks logged-in users in the roles you choose to accept your Terms &amp; Conditions, and keeps a verifiable record of who accepted which version, and when.<\/p>\n\n<ul>\n<li><strong>Versioned archive.<\/strong> Every published version is stored in full and never deleted, so each acceptance can be tied to the exact text shown.<\/li>\n<li><strong>Tamper-evident log.<\/strong> Each record is signed twice (immutable core, erasable context) and chained to the previous one. A verifier on the log screen flags altered rows.<\/li>\n<li><strong>Role-scoped prompt.<\/strong> A popup with \"skip for now\" (not recorded) and a persistent admin notice until the user accepts.<\/li>\n<li><strong>Receipts.<\/strong> An acceptance confirmation e-mailed to the user, with a PDF copy of what was accepted attached when the bundled PDF library is present.<\/li>\n<li><strong>GDPR tooling.<\/strong> Personal-data exporter and eraser, retention-based anonymisation, and suggested privacy policy text.<\/li>\n<li><strong>Manage it your way.<\/strong> Admin screens, a REST API (<code>mmwp\/v1<\/code>), WP-CLI (<code>wp mmwp terms<\/code>) and the WordPress Abilities API (read-only <code>list-acceptances<\/code> and more).<\/li>\n<li><strong>A public block<\/strong> that shows the current terms, effective date and history.<\/li>\n<\/ul>\n\n<h4>This is not a consent plugin<\/h4>\n\n<p>Recording acceptance of terms is an access-control and contractual-compliance mechanism (GDPR Art. 6(1)(b) and 6(1)(f)), not consent under Art. 6(1)(a). Acceptance is therefore not withdrawable and records are not deleted on request; see the FAQ.<\/p>\n\n<h4>Privacy and external services<\/h4>\n\n<p>The plugin makes no outbound requests, loads no remote scripts, fonts or images, and sends no telemetry. It never phones home. It sends e-mail in two cases, both through your site's normal <code>wp_mail()<\/code>: the acceptance receipt to the accepting user only (the PDF copy is attached when the bundled PDF library is present), and, only when an administrator presses Send on the Support screen (Mammoth WP &gt; Support), a support request to info@mammothwp.com. The support request includes a site report only if the administrator ticks the box after previewing the exact text. Nothing is ever sent automatically.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Install and activate the plugin from <strong>Plugins &gt; Add New<\/strong>, or upload the zip.<\/li>\n<li>Go to <strong>Settings &gt; Terms &amp; Conditions<\/strong> and write your terms.<\/li>\n<li>Choose which roles must accept them, then publish the version.<\/li>\n<\/ol>\n\n<p>Users in the selected roles are prompted the next time they load the site or the dashboard while logged in. Whoever activated the plugin becomes its first manager; managers are the only people who can read the acceptance log. Records appear under <strong>Users &gt; Terms acceptance log<\/strong>.<\/p>\n\n<!--section=faq-->\n<dl>\n<dt id=\"is%20this%20a%20cookie%20or%20consent%20plugin%3F\"><h3>Is this a cookie or consent plugin?<\/h3><\/dt>\n<dd><p>No, and the distinction drives the whole design. Accepting Terms &amp; Conditions\nis an access-control and contractual-compliance mechanism resting on\nArt. 6(1)(b) and 6(1)(f) GDPR, not consent under Art. 6(1)(a). Practically:\nacceptance is not withdrawable in the Art. 7(3) sense, and records are not\ndeleted on request. If you need cookie consent, you need a different plugin \u2014\nrun both.<\/p><\/dd>\n<dt id=\"which%20roles%20are%20prompted%3F\"><h3>Which roles are prompted?<\/h3><\/dt>\n<dd><p>Until you choose, <strong>every role<\/strong>. The plugin does not guess a safe subset, and\npicking the roles is step 3 of the setup for that reason. Settings \u2192 Terms &amp;\nConditions lists every role on the site.<\/p><\/dd>\n<dt id=\"does%20it%20lock%20users%20out%20until%20they%20accept%3F\"><h3>Does it lock users out until they accept?<\/h3><\/dt>\n<dd><p>No. The popup has a \"skip for now\" button, and a user who clicks it keeps\nworking. Skipping is not recorded as an acceptance or a decline: it only hides\nthe popup for that user for 12 hours (filterable with\n    mmwp_terms_skip_duration) and fires the <code>mmwp_terms_skipped<\/code> action; nothing\nis written to the acceptance log or audit events. What persists is a\nnon-dismissable notice on every wp-admin screen, shown only to logged-in users\nin scope who have not accepted the current version, until they accept. It is a prompt with no exit, not a wall \u2014 a hard lockout\nrisks stranding an administrator who needs the backend to fix the terms.<\/p><\/dd>\n<dt id=\"what%20happens%20when%20i%20edit%20the%20terms%3F\"><h3>What happens when I edit the terms?<\/h3><\/dt>\n<dd><p>Editing and publishing creates a <strong>new version<\/strong> with the next sequential\nnumber, archives the full text permanently, and re-prompts everyone in scope.\nPrevious versions are never deleted, and republishing earlier text is a new\npublication with a new number rather than a silent return to an old one \u2014 so\n\"revert the text and everyone counts as accepted again\" cannot happen.<\/p>\n\n<p>Changing the text without publishing changes nothing. The daily cron only\npicks up changes made through a content source that bypasses the settings\nscreen.<\/p><\/dd>\n<dt id=\"can%20a%20user%20withdraw%20their%20acceptance%3F\"><h3>Can a user withdraw their acceptance?<\/h3><\/dt>\n<dd><p>No. The record is evidence that a particular version was accepted at a\nparticular moment; that fact does not stop being true. A user who\ndoes not want to accept can only skip the popup for now; that is not recorded\n(see above), and the acceptance prompt returns until they accept.<\/p><\/dd>\n<dt id=\"how%20do%20i%20handle%20an%20erasure%20request%3F\"><h3>How do I handle an erasure request?<\/h3><\/dt>\n<dd><p>Through WordPress's own Tools \u2192 Erase Personal Data \u2014 the plugin registers an\neraser. It returns the acceptance records as <strong>retained<\/strong>, with the reasoning\nshown to the requester rather than applied silently, and erases the context\n(IP, User-Agent) of any record already past its retention period. Art. 17(3)(b)\nand (e) disapply the right to erasure where processing is necessary for legal\nclaims, which is what proof of acceptance is. See the retention policy document in the plugin repository.<\/p><\/dd>\n<dt id=\"how%20long%20is%20data%20kept%3F\"><h3>How long is data kept?<\/h3><\/dt>\n<dd><p>Records live while the account exists, plus a dispute period defaulting to\nfive years, after which the IP address, IP source and User-Agent are erased\nand the record is retained in anonymised form. Records are anonymised, never\ndeleted. Published versions of the terms are never deleted at all \u2014 an\nacceptance whose text cannot be reproduced proves almost nothing.<\/p><\/dd>\n<dt id=\"i%27m%20an%20administrator.%20why%20can%27t%20i%20see%20the%20acceptance%20log%3F\"><h3>I'm an administrator. Why can't I see the acceptance log?<\/h3><\/dt>\n<dd><p>Access is an explicit list of user accounts, not a capability. That is\ndeliberate: <code>manage_options<\/code> gets handed out liberally by role plugins and\nduring onboarding, and the log is evidence about other people. Whoever\nactivated the plugin is the first manager and can appoint others; the last\nmanager cannot be removed.<\/p><\/dd>\n<dt id=\"can%20i%20delete%20a%20record%2C%20or%20fix%20a%20wrong%20one%3F\"><h3>Can I delete a record, or fix a wrong one?<\/h3><\/dt>\n<dd><p>No, by design. There is no update or delete path in the code and no edit or\ndelete affordance in the admin. If a record is wrong, the answer is a new\nrecord plus an audit event. Their absence is the control, not an oversight.<\/p><\/dd>\n<dt id=\"does%20it%20work%20behind%20cloudflare%20or%20a%20load%20balancer%3F\"><h3>Does it work behind Cloudflare or a load balancer?<\/h3><\/dt>\n<dd><p>Yes, but configure the trusted proxies first or the audit log records the\nproxy's address instead of the visitor's. Return your proxy's address or CIDR range\nfrom the <code>mmwp_terms_trusted_proxies<\/code> filter. Forwarded IP headers are ignored by default because trusting\nthem unconditionally would let any client write its own address into the log.<\/p><\/dd>\n<dt id=\"does%20it%20support%20multisite%3F\"><h3>Does it support multisite?<\/h3><\/dt>\n<dd><p>Each site gets its own tables and settings, so activate it per site. Network\nactivation is not supported: the tables are created for the site the\nactivation runs on, not for every site in the network.<\/p><\/dd>\n<dt id=\"where%20do%20i%20get%20evidence%20for%20a%20dispute%3F\"><h3>Where do I get evidence for a dispute?<\/h3><\/dt>\n<dd><p>Users \u2192 Terms acceptance log, which shows every record with its integrity and\ndelivery status, filterable, with CSV export and an on-demand integrity check.\n    the evidence-handling document in the plugin repository covers the procedure, what the evidence actually\nshows, and the limitations you should disclose alongside it.<\/p><\/dd>\n<dt id=\"what%20personal%20data%20is%20stored%3F\"><h3>What personal data is stored?<\/h3><\/dt>\n<dd><p>Per acceptance: user ID, login and e-mail as they were at the time, the version accepted, UTC and local timestamps with timezone, the site identifier, IP address (and how it was determined), User-Agent and cryptographic signatures. Three user-meta markers record the version each user accepted. No fingerprinting, MAC address or geolocation is collected.<\/p><\/dd>\n<dt id=\"does%20it%20support%20the%20wordpress%20personal%20data%20tools%3F\"><h3>Does it support the WordPress personal data tools?<\/h3><\/dt>\n<dd><p>Yes. It registers a personal-data exporter and eraser (<code>wp_privacy_personal_data_exporters<\/code>, <code>wp_privacy_personal_data_erasers<\/code>) and adds suggested text to the Privacy Policy guide with <code>wp_add_privacy_policy_content()<\/code>.<\/p><\/dd>\n<dt id=\"does%20it%20contact%20any%20external%20service%3F\"><h3>Does it contact any external service?<\/h3><\/dt>\n<dd><p>No. There are no remote calls, no CDN assets, no update checks and no telemetry. The bundled Support screen (Mammoth WP &gt; Support) sends one e-mail through <code>wp_mail()<\/code> to info@mammothwp.com, only when an administrator presses Send. A site report is attached only if they tick \"Include site report\" after previewing exactly what it contains.<\/p><\/dd>\n<dt id=\"what%20happens%20when%20i%20delete%20the%20plugin%3F\"><h3>What happens when I delete the plugin?<\/h3><\/dt>\n<dd><p>By default the acceptance evidence is kept. When you click Delete on the Plugins screen, a dialog asks whether to <strong>keep the acceptance evidence (recommended)<\/strong> or <strong>delete it permanently<\/strong>; deleting requires typing the plugin name. Either way the plugin's settings, scheduled tasks and options are removed. If you keep the evidence, the log, the version archive, the audit events, the per-user acceptance markers and the signing key stay in your database, so they can still be verified later.<\/p>\n\n<p>You can change the choice at any time under Settings &gt; Terms &amp; Conditions, or purge the evidence immediately with <code>wp mmwp terms purge<\/code> (it only reports what exists; add <code>--force<\/code> to delete, <code>--dry-run<\/code> to never delete). Developers can override the choice with the <code>mmwp_terms_drop_data_on_uninstall<\/code> filter.<\/p><\/dd>\n<dt id=\"can%20i%20manage%20it%20without%20the%20admin%20screens%3F\"><h3>Can I manage it without the admin screens?<\/h3><\/dt>\n<dd><p>Yes: REST (<code>mmwp\/v1\/terms\/...<\/code>), WP-CLI (<code>wp mmwp terms ...<\/code>) and the Abilities API, all declared once. Reading the acceptance log over any of them requires being a plugin manager and returns a redacted shape (no IP address, User-Agent or e-mail).<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>First release on wordpress.org. See CHANGELOG.md for the full history.<\/li>\n<\/ul>","raw_excerpt":"Log that your users accepted your terms: versioned, role-scoped, tamper-evident, with a permanent archive of every version.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/394664","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=394664"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/mammothwp"}],"wp:attachment":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=394664"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=394664"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=394664"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=394664"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=394664"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=394664"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}