From 9270e457c6bdb6dcd91cc816bc871e56775c9ef8 Mon Sep 17 00:00:00 2001
From: anon
Date: Thu, 10 Oct 2024 17:10:14 +0000
Subject: [PATCH] initial commit
---
antisocial-safety.php | 460 ++++++++++++++++++++++++++++++++++++++++++
readme.md | 50 +++++
2 files changed, 510 insertions(+)
create mode 100644 antisocial-safety.php
create mode 100644 readme.md
diff --git a/antisocial-safety.php b/antisocial-safety.php
new file mode 100644
index 0000000..0ebfcee
--- /dev/null
+++ b/antisocial-safety.php
@@ -0,0 +1,460 @@
+ 'omni-moderation-latest',
+ 'input' => array(
+ array(
+ 'type' => 'image_url',
+ 'image_url' => array('url' => $image_url),
+ ),
+ ),
+ );
+
+ $args = array(
+ 'headers' => array(
+ 'Content-Type' => 'application/json',
+ 'Authorization' => 'Bearer ' . $api_key,
+ ),
+ 'body' => wp_json_encode($data),
+ 'timeout' => 60,
+ );
+
+ $response = wp_remote_post($endpoint, $args);
+
+ if (is_wp_error($response)) {
+ // For graceful failure, return an empty array
+ return array();
+ }
+
+ $body = wp_remote_retrieve_body($response);
+ $result = json_decode($body, true);
+
+ if (isset($result['results'][0])) {
+ return $result['results'][0];
+ } else {
+ // Invalid response; return an empty array
+ return array();
+ }
+}
+
+// Hook into 'template_redirect' to block access to flagged attachments
+add_action('template_redirect', 'oai_block_flagged_attachments');
+
+function oai_block_flagged_attachments() {
+ if (is_attachment()) {
+ global $post;
+ if ($post) {
+ $flagged = get_post_meta($post->ID, '_oai_moderation_flagged', true);
+ if ($flagged) {
+ // Send 403 Forbidden header and exit
+ status_header(403);
+ nocache_headers();
+ // Optionally, display a message
+ wp_die(__('You are not allowed to access this content.', 'oai'), __('Forbidden', 'oai'), array('response' => 403));
+ }
+ }
+ }
+}
+
+/**
+ * Comments Moderation
+ */
+
+// Moderate comments before saving
+add_filter('preprocess_comment', 'oai_moderate_comment');
+
+function oai_moderate_comment($commentdata) {
+ $api_key = get_option('oai_api_key');
+ if (!$api_key) {
+ return $commentdata; // If API key not set, let the comment pass
+ }
+
+ $comment_content = $commentdata['comment_content'];
+
+ // Moderate the comment text
+ $result = oai_moderate_text($comment_content);
+
+ if (isset($result['error'])) {
+ // Handle error (optional: log the error)
+ // For graceful failure, let the comment pass
+ return $commentdata;
+ }
+
+ // Store the moderation result in a global variable indexed by comment content hash
+ $hash = md5($comment_content);
+ global $oai_moderation_results;
+ $oai_moderation_results[$hash] = $result;
+
+ return $commentdata;
+}
+
+// Set the comment approval status based on moderation result
+add_filter('pre_comment_approved', 'oai_set_comment_approval_status', 10, 2);
+
+function oai_set_comment_approval_status($approved, $commentdata) {
+ $api_key = get_option('oai_api_key');
+ if (!$api_key) {
+ return $approved; // Let the comment pass if API key not set
+ }
+
+ $comment_content = $commentdata['comment_content'];
+ $hash = md5($comment_content);
+
+ global $oai_moderation_results;
+ if (isset($oai_moderation_results[$hash])) {
+ $result = $oai_moderation_results[$hash];
+ if ($result['flagged']) {
+ // Set comment to unapproved
+ return '0'; // Unapproved
+ }
+ }
+ return $approved;
+}
+
+// Save the moderation result after the comment is inserted
+add_action('comment_post', 'oai_save_comment_moderation_meta', 10, 2);
+
+function oai_save_comment_moderation_meta($comment_ID, $comment_approved) {
+ $comment = get_comment($comment_ID);
+ $comment_content = $comment->comment_content;
+ $hash = md5($comment_content);
+
+ global $oai_moderation_results;
+ if (isset($oai_moderation_results[$hash])) {
+ $result = $oai_moderation_results[$hash];
+ update_comment_meta($comment_ID, '_oai_moderation_result', $result);
+ update_comment_meta($comment_ID, '_oai_moderation_flagged', $result['flagged'] ? 'pending' : 'ok');
+ // Remove from global variable
+ unset($oai_moderation_results[$hash]);
+ }
+}
+
+function oai_moderate_text($text) {
+ $api_key = get_option('oai_api_key');
+ if (!$api_key) {
+ // API key not set; skip moderation
+ return array(); // Return an empty array indicating no moderation
+ }
+
+ $endpoint = 'https://api.openai.com/v1/moderations';
+
+ $data = array(
+ 'model' => 'omni-moderation-latest',
+ 'input' => array(
+ array(
+ 'type' => 'text',
+ 'text' => $text,
+ ),
+ ),
+ );
+
+ $args = array(
+ 'headers' => array(
+ 'Content-Type' => 'application/json',
+ 'Authorization' => 'Bearer ' . $api_key,
+ ),
+ 'body' => wp_json_encode($data),
+ 'timeout' => 60,
+ );
+
+ $response = wp_remote_post($endpoint, $args);
+
+ if (is_wp_error($response)) {
+ // For graceful failure, return an empty array
+ return array();
+ }
+
+ $body = wp_remote_retrieve_body($response);
+ $result = json_decode($body, true);
+
+ if (isset($result['results'][0])) {
+ return $result['results'][0];
+ } else {
+ // Invalid response; return an empty array
+ return array();
+ }
+}
+
+/**
+ * Admin Columns for Media and Comments
+ */
+
+// Add a custom column to the media library
+add_filter('manage_media_columns', 'oai_add_media_column');
+function oai_add_media_column($columns) {
+ $columns['oai_moderation'] = __('Moderation', 'oai');
+ return $columns;
+}
+
+add_action('manage_media_custom_column', 'oai_media_column_content', 10, 2);
+function oai_media_column_content($column_name, $post_ID) {
+ if ($column_name == 'oai_moderation') {
+ $flagged = get_post_meta($post_ID, '_oai_moderation_flagged', true);
+ if ($flagged) {
+ echo '' . __('Flagged', 'oai') . ' ';
+ } else {
+ echo '' . __('OK', 'oai') . ' ';
+ }
+ }
+}
+
+// Add a custom column to the comments list
+add_filter('manage_edit-comments_columns', 'oai_add_comments_column');
+function oai_add_comments_column($columns) {
+ $columns['oai_moderation'] = __('Moderation', 'oai');
+ return $columns;
+}
+
+add_action('manage_comments_custom_column', 'oai_comments_column_content', 10, 2);
+function oai_comments_column_content($column_name, $comment_ID) {
+ if ($column_name == 'oai_moderation') {
+ $flagged = get_comment_meta($comment_ID, '_oai_moderation_flagged', true);
+ if ($flagged === 'pending') {
+ echo '' . __('Pending Approval', 'oai') . ' ';
+ } elseif ($flagged === 'flagged') {
+ echo '' . __('Flagged', 'oai') . ' ';
+ } else {
+ echo '' . __('OK', 'oai') . ' ';
+ }
+ }
+}
+
+/**
+ * Display Moderation Details in Admin Screens
+ */
+
+// Add moderation info to the attachment edit screen
+add_filter('attachment_fields_to_edit', 'oai_attachment_fields', 10, 2);
+function oai_attachment_fields($form_fields, $post) {
+ $api_key = get_option('oai_api_key');
+ if (!$api_key) {
+ // API key not set; do not display moderation fields
+ return $form_fields;
+ }
+
+ $flagged = get_post_meta($post->ID, '_oai_moderation_flagged', true);
+ $moderation_result = get_post_meta($post->ID, '_oai_moderation_result', true);
+
+ if ($flagged) {
+ $form_fields['oai_moderation'] = array(
+ 'label' => __('OpenAI Moderation', 'oai'),
+ 'input' => 'html',
+ 'html' => '' . __('This attachment has been flagged by OpenAI Moderation.', 'oai') . ' ',
+ 'helps' => __('Flagged content is blocked from being served to users.', 'oai'),
+ );
+ } else {
+ $form_fields['oai_moderation'] = array(
+ 'label' => __('OpenAI Moderation', 'oai'),
+ 'input' => 'html',
+ 'html' => '' . __('This attachment passed OpenAI Moderation.', 'oai') . ' ',
+ );
+ }
+
+ if ($moderation_result) {
+ $form_fields['oai_moderation_result'] = array(
+ 'label' => __('Moderation Details', 'oai'),
+ 'input' => 'html',
+ 'html' => '' . esc_html(print_r($moderation_result, true)) . ' ',
+ );
+ }
+
+ return $form_fields;
+}
+
+// Add a meta box to the comment edit screen for moderation details
+add_action('add_meta_boxes_comment', 'oai_add_comment_meta_box');
+function oai_add_comment_meta_box() {
+ add_meta_box(
+ 'oai_comment_moderation',
+ __('OpenAI Moderation Details', 'oai'),
+ 'oai_comment_moderation_meta_box',
+ 'comment',
+ 'normal',
+ 'high'
+ );
+}
+
+function oai_comment_moderation_meta_box($comment) {
+ $api_key = get_option('oai_api_key');
+ if (!$api_key) {
+ // API key not set; do not display moderation details
+ return;
+ }
+
+ $moderation_result = get_comment_meta($comment->comment_ID, '_oai_moderation_result', true);
+ $flagged = get_comment_meta($comment->comment_ID, '_oai_moderation_flagged', true);
+
+ if ($flagged) {
+ echo '' . __('Status:', 'oai') . ' ';
+ if ($flagged === 'pending') {
+ echo '' . __('Pending Approval', 'oai') . ' ';
+ } elseif ($flagged === 'flagged') {
+ echo '' . __('Flagged', 'oai') . ' ';
+ }
+ echo '
';
+
+ if ($moderation_result) {
+ echo '' . __('Moderation Details', 'oai') . ' ';
+ echo '' . esc_html(print_r($moderation_result, true)) . ' ';
+ }
+ } else {
+ echo '' . __('This comment passed OpenAI Moderation.', 'oai') . '
';
+ }
+}
+
+/**
+ * Settings Page
+ */
+
+// Add settings page under Settings menu
+add_action('admin_menu', 'oai_add_admin_menu');
+
+function oai_add_admin_menu() {
+ add_options_page(
+ __('OpenAI Moderation', 'oai'),
+ __('OpenAI Moderation', 'oai'),
+ 'manage_options',
+ 'openai-moderation',
+ 'oai_options_page'
+ );
+}
+
+function oai_options_page() {
+ ?>
+
+
+
+
+ ' . esc_html__('Enter your OpenAI API key to enable moderation.', 'oai') . '';
+}
+
+function oai_api_key_render() {
+ $api_key = get_option('oai_api_key');
+ ?>
+
+ id !== 'settings_page_openai-moderation') {
+ return;
+ }
+
+ $api_key = get_option('oai_api_key');
+ if (!$api_key) {
+ echo '
+
' . __('OpenAI API key is not set. Moderation features are disabled until you enter a valid API key.', 'oai') . '
+
';
+ }
+}
\ No newline at end of file
diff --git a/readme.md b/readme.md
new file mode 100644
index 0000000..671ebaf
--- /dev/null
+++ b/readme.md
@@ -0,0 +1,50 @@
+# openai moderation for attachments and comments
+
+running a small website can be a hassle when idiots upload nasty stuff or spam your comments. this plugin uses openai's moderation api to automatically check images and comments for bad content.
+
+## why use this plugin?
+
+it keeps your site clean by blocking offensive or illegal images and comments before they become a problem. saves you headaches.
+
+## features
+
+- **attachment moderation**: images are checked during upload. flagged images are blocked from being accessed.
+- **comment moderation**: comments are reviewed before they're saved. flagged comments are set to unapproved.
+- **admin integration**: see moderation status directly in your media library and comments list. detailed info available in edit screens.
+- **easy setup**: just add your openai api key in the settings.
+
+## installation
+
+1. upload the plugin files to `/wp-content/plugins/`, or install through the wordpress plugins screen.
+2. activate the plugin.
+3. go to `settings` > `openai moderation` and enter your openai api key.
+
+## how it works
+
+### attachment moderation
+
+- when an image is uploaded, the plugin sends it to openai's moderation api using the `omni-moderation-latest` model.
+- if the image is flagged, the plugin blocks access to it by sending a 403 forbidden response when someone tries to view it.
+
+### comment moderation
+
+- before a comment is saved, the plugin checks the content with openai's moderation api.
+- flagged comments are set to unapproved, so they won't show up on your site unless you approve them.
+
+### backend functionality
+
+- hooks into `add_attachment` to moderate images upon upload.
+- uses `template_redirect` to block access to flagged attachments.
+- hooks into `preprocess_comment` and `pre_comment_approved` to moderate comments before saving.
+- stores moderation results in post and comment meta.
+- adds custom columns in admin screens to display moderation status.
+- provides detailed moderation info in the attachment and comment edit screens.
+
+## requirements
+
+- wordpress 5.0 or higher
+- an openai api key
+
+## notes
+
+- if the openai api key isn't set, the plugin won't function.