@prefix sioc: <http://rdfs.org/sioc/ns#> .
@prefix dc: <http://purl.org/dc/elements/1.1/> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix content: <http://purl.org/rss/1.0/modules/content/> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .

<https://lhero.org/portfolio/lh-comment-moderation/>
  a sioc:Post ;
  dc:title "Notes" ;
  dcterms:identifier 152473 ;
  dc:modified "2026-10-25T17:28:27Z"^^xsd:dateTime ;
  dc:created "2026-10-25T17:09:05Z"^^xsd:dateTime ;
  sioc:link <https://lhero.org/portfolio/lh-comment-moderation/notes/> ;
  sioc:has_creator <https://lhero.org/author/1/#account> ;
  sioc:has_container <https://lhero.org/#posts> ;
  content:encoded """<ul class="lh_portfolio-meta"><li><strong>Part of:</strong> <a href="https://lhero.org/portfolio/lh-comment-moderation/">LH Comment Moderation</a></li></ul>
<h2 class="wp-block-heading">One moderation path</h2>



<p class="wp-block-paragraph">Every change goes through <code>LH_Comment_Moderation_Moderator</code>, whether an ability or a front-end link asked for it, so the rules and the audit trail are the same for an AI agent and for a moderator on the page. It uses core&#8217;s own functions (<code>wp_set_comment_status()</code>, <code>wp_spam_comment()</code>, <code>wp_trash_comment()</code> and their undo counterparts, <code>wp_update_post()</code>), so every core and plugin hook on those actions still fires.</p>



<h2 class="wp-block-heading">Front-end links</h2>



<p class="wp-block-paragraph"><code>LH_Comment_Moderation_Frontend</code> adds Unapprove (Approve on a held comment), Spam, Trash and Edit links after the comment text, through <code>comment_text</code> at priority 100, added on <code>template_redirect</code>. Links appear only for logged-in users with <code>moderate_comments</code> and <code>edit_comment</code>, on singular views, in the page body (after <code>wp_body_open</code>, or the block-template render window), never in feeds. Each link goes to <code>admin-post.php?action=lh_comment_moderation_frontend</code> with a nonce tied to the action and the comment, runs the action with source <code>web</code>, then returns to the referring page. Filter <code>lh_comment_moderation_return_link_actions</code> to change which actions are offered. Markup classes: <code>lh-comment-moderation-links</code> on the wrapper and <code>lh-comment-moderation-{action}</code> on each link; no stylesheet is shipped.</p>



<h2 class="wp-block-heading">Nothing is deleted</h2>



<ul class="wp-block-list">
<li>Trash is the furthest anything goes. When a site sets <code>EMPTY_TRASH_DAYS</code> to 0, core&#8217;s <code>wp_trash_comment()</code> deletes permanently instead, so trash is refused there.</li>



<li>A spam or trashed comment must be unspammed or untrashed before it is approved or held. Undoing restores the status it had before, from core&#8217;s own restore metadata, which a direct status change would leave behind.</li>
</ul>



<h2 class="wp-block-heading">Permissions and sites</h2>



<p class="wp-block-paragraph">Every ability needs <code>moderate_comments</code> on the site it acts on (filter: <code>lh_comment_moderation_return_required_capability</code>), plus <code>edit_comment</code> for each comment or <code>edit_post</code> for each post. The abilities are registered with <code>meta.site_scoped</code>, so with LH MCP Adapter Extensions active they take an optional <code>site_id</code> and run on that site, with the permission checked there. The plugin must be network-activated for that to reach every site.</p>



<h2 class="wp-block-heading">Audit trail</h2>



<p class="wp-block-paragraph">With LH Audit Trail active, each change records <code>comment.moderated</code> (action, before and after status, post, source <code>mcp</code> or <code>web</code>) or <code>post.discussion_changed</code> (before and after settings, source), with the current user as actor and the comment&#8217;s or post&#8217;s author as subject. Both are kept 370 days, readable with <code>moderate_comments</code>, and not shown on members&#8217; own audit trails.</p>



<h2 class="wp-block-heading">Origin</h2>



<p class="wp-block-paragraph">Built for lh-tasks #152464, after a site audit found no way to moderate comments without wp-admin. 0.3.0 absorbed LH Frontend Comment Moderation (lh-tasks #152474), which is retired.</p>
"""^^rdf:XMLLiteral ;
  sioc:content """Part of: LH Comment Moderation
One moderation path



Every change goes through LH_Comment_Moderation_Moderator, whether an ability or a front-end link asked for it, so the rules and the audit trail are the same for an AI agent and for a moderator on the page. It uses core&#8217;s own functions (wp_set_comment_status(), wp_spam_comment(), wp_trash_comment() and their undo counterparts, wp_update_post()), so every core and plugin hook on those actions still fires.



Front-end links



LH_Comment_Moderation_Frontend adds Unapprove (Approve on a held comment), Spam, Trash and Edit links after the comment text, through comment_text at priority 100, added on template_redirect. Links appear only for logged-in users with moderate_comments and edit_comment, on singular views, in the page body (after wp_body_open, or the block-template render window), never in feeds. Each link goes to admin-post.php?action=lh_comment_moderation_frontend with a nonce tied to the action and the comment, runs the action with source web, then returns to the referring page. Filter lh_comment_moderation_return_link_actions to change which actions are offered. Markup classes: lh-comment-moderation-links on the wrapper and lh-comment-moderation-{action} on each link; no stylesheet is shipped.



Nothing is deleted




Trash is the furthest anything goes. When a site sets EMPTY_TRASH_DAYS to 0, core&#8217;s wp_trash_comment() deletes permanently instead, so trash is refused there.



A spam or trashed comment must be unspammed or untrashed before it is approved or held. Undoing restores the status it had before, from core&#8217;s own restore metadata, which a direct status change would leave behind.




Permissions and sites



Every ability needs moderate_comments on the site it acts on (filter: lh_comment_moderation_return_required_capability), plus edit_comment for each comment or edit_post for each post. The abilities are registered with meta.site_scoped, so with LH MCP Adapter Extensions active they take an optional site_id and run on that site, with the permission checked there. The plugin must be network-activated for that to reach every site.



Audit trail



With LH Audit Trail active, each change records comment.moderated (action, before and after status, post, source mcp or web) or post.discussion_changed (before and after settings, source), with the current user as actor and the comment&#8217;s or post&#8217;s author as subject. Both are kept 370 days, readable with moderate_comments, and not shown on members&#8217; own audit trails.



Origin



Built for lh-tasks #152464, after a site audit found no way to moderate comments without wp-admin. 0.3.0 absorbed LH Frontend Comment Moderation (lh-tasks #152474), which is retired.
""" ;
  sioc:topic <https://lhero.org/?taxonomy=author&term=cap-1> .

<https://lhero.org/author/1/#account> rdfs:seeAlso <https://lhero.org/author/1/?feed=lhrdf&format=turtle> .
<https://lhero.org/?taxonomy=author&term=cap-1> rdfs:seeAlso <https://lhero.org/?taxonomy=author&term=cap-1&feed=lhrdf&format=turtle> .
