diff --git a/README.md b/README.md index f6af945bb3cc9e42fdb52d35f8dd209fbbfaddd4..40a0f811d3b2cc9a4b0f69f5e2f2a67e116bebb4 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ | ---------- | ------------------------------------------------------------ | | 中文名称 | 腾讯云图片内容安全(IMS)插件 | | 英文名称 | tencentcloud-ims | -| 最新版本 | v1.0.1 (2020.12.11) | +| 最新版本 | v1.0.2 (2021.5.8) | | 适用平台 | [WordPress](https://wordpress.org/) | | 适用产品 | [腾讯云图片内容安全(IMS)](https://cloud.tencent.com/product/ims) | | 文档中心 | [春雨文档中心](https://openapp.qq.com/docs/Wordpress/ims.html) | @@ -45,6 +45,8 @@  > 对发文章时上传的图片进行检测,检测不通过将会提示如上信息 + +> 可以查询到所有违规的图片上传记录信息 ### 4.2.名词解释 - **自定义密钥:** 插件提供统一密钥管理,既可在多个腾讯云插件之间共享SecretId和SecretKey,也可为插件配置单独定义的腾讯云密钥。 @@ -64,6 +66,8 @@ > 暂无 ## 7.GitHub版本迭代记录 +### 2021.05.08 tencentcloud-wordpress-plugin-ims v1.0.2 +- 新增违规图片上传记录功能 ### 2020.12.11 tencentcloud-wordpress-plugin-ims v1.0.1 - 支持在windows环境下运行 diff --git a/images/ims4.png b/images/ims4.png new file mode 100644 index 0000000000000000000000000000000000000000..5e128db62492685f65d8781f0b3d959621e38ad5 Binary files /dev/null and b/images/ims4.png differ diff --git a/tencentcloud-ims/TencentWordPressIMSActions.php b/tencentcloud-ims/TencentWordPressIMSActions.php index 5e779fe11b8fa1daea990fa6a8916c0e8f98fb02..1c53110053644fa34e8a36ab15233cfaa4b6d670 100644 --- a/tencentcloud-ims/TencentWordPressIMSActions.php +++ b/tencentcloud-ims/TencentWordPressIMSActions.php @@ -29,7 +29,8 @@ use TencentWordpressPluginsSettingActions; class TencentWordPressIMSActions { - const PLUGIN_TYPE ='ims'; + const PLUGIN_TYPE = 'ims'; + const IMAGE_RECORD_TABLE_NAME = 'tencent_wordpress_ims_image_records'; /** * 插件初始化 @@ -37,6 +38,7 @@ class TencentWordPressIMSActions public static function initPlugin() { static::addToPluginCenter(); + static::createIMSImageRecordTable(); // 第一次开启插件则生成一个全站唯一的站点id,保存在公共的option中 self::requirePluginCenterClass(); TencentWordpressPluginsSettingActions::setWordPressSiteID(); @@ -81,6 +83,33 @@ class TencentWordPressIMSActions TencentWordpressPluginsSettingActions::prepareTencentWordressPluginsDB($plugin); } + /** + * 创建敏感词命中记录表 + * @return bool + */ + public static function createIMSImageRecordTable() + { + $wpdb = $GLOBALS['wpdb']; + $tableName = $wpdb->prefix . self::IMAGE_RECORD_TABLE_NAME; + if ($wpdb->get_var("SHOW TABLES LIKE '{$tableName}'") !== $tableName) { + $sql = "CREATE TABLE IF NOT EXISTS `{$tableName}` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `user_login` varchar(100) NOT NULL DEFAULT '', + `user_nicename` varchar(100) NOT NULL DEFAULT '', + `user_email` varchar(32) NOT NULL DEFAULT '', + `user_role` varchar(32) NOT NULL DEFAULT '', + `status` varchar(50) NOT NULL DEFAULT '', + `type` varchar(50) NOT NULL DEFAULT '', + `file_name` varchar(200) NOT NULL DEFAULT '', + `create_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`id`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"; + require_once(ABSPATH . 'wp-admin/includes/upgrade.php'); + dbDelta($sql); + } + return true; + } + /** * 初始化插件中心设置页面 */ @@ -98,7 +127,8 @@ class TencentWordPressIMSActions public static function uninstallPlugin() { self::requirePluginCenterClass(); - delete_option( TENCENT_WORDPRESS_IMS_OPTIONS ); + self::deleteIMSImageRecordTable(); + delete_option(TENCENT_WORDPRESS_IMS_OPTIONS); TencentWordpressPluginsSettingActions::deleteTencentWordpressPlugin(TENCENT_WORDPRESS_IMS_SHOW_NAME); $staticData = self::getTencentCloudWordPressStaticData('uninstall'); TencentWordpressPluginsSettingActions::sendUserExperienceInfo($staticData); @@ -115,7 +145,7 @@ class TencentWordPressIMSActions $staticData['data']['site_app'] = TencentWordpressPluginsSettingActions::getWordPressSiteApp(); $IMSOptions = self::getIMSOptionsObject(); $staticData['data']['uin'] = TencentWordpressPluginsSettingActions::getUserUinBySecret($IMSOptions->getSecretID(), $IMSOptions->getSecretKey()); - $staticData['data']['cust_sec_on'] = $IMSOptions->getCustomKey() === $IMSOptions::CUSTOM_KEY ?1:2; + $staticData['data']['cust_sec_on'] = $IMSOptions->getCustomKey() === $IMSOptions::CUSTOM_KEY ? 1 : 2; return $staticData; } @@ -125,9 +155,9 @@ class TencentWordPressIMSActions * @param string $default * @return string|void */ - public function filterPostParam($key ,$default = '') + public function filterPostParam($key, $default = '') { - return isset($_POST[$key])?sanitize_text_field($_POST[$key]):$default; + return isset($_POST[$key]) ? sanitize_text_field($_POST[$key]) : $default; } /** @@ -136,7 +166,7 @@ class TencentWordPressIMSActions */ public static function getIMSOptionsObject() { - $IMSOptions = get_option( TENCENT_WORDPRESS_IMS_OPTIONS ); + $IMSOptions = get_option(TENCENT_WORDPRESS_IMS_OPTIONS); if ($IMSOptions instanceof TencentWordpressIMSOptions) { return $IMSOptions; } @@ -154,7 +184,7 @@ class TencentWordPressIMSActions { $IMSOptions = self::getIMSOptionsObject(); $imgContent = file_get_contents($file['tmp_name']); - $response = $this->imageModeration($IMSOptions,$imgContent); + $response = $this->imageModeration($IMSOptions, $imgContent); //检测接口异常不进行报错 if (!($response instanceof ImageModerationResponse)) { return $file; @@ -162,6 +192,19 @@ class TencentWordPressIMSActions if ($response->getData()->EvilFlag === 0 || $response->getData()->EvilType === 100) { return $file; } + + // 命中记录入库 + $user = wp_get_current_user(); + $user_login = $user->data->user_login; + $user_nicename = $user->data->user_nicename; + $user_email = $user->data->user_email; + $user_role = $user->roles[0]; + $status = '上传失败'; + $type = 'picture'; + $file_name = $file['name']; + $create_time = date('Y-m-d H:i:s', time()); + $this->insertIMSImageRecord($user_login, $user_nicename, $user_email, + $user_role, $status, $type, $file_name, $create_time); $file['error'] = '图片检测不通过,请更换'; return $file; } @@ -174,7 +217,7 @@ class TencentWordPressIMSActions * @return bool * @throws Exception */ - public function examineImageInPost($data, $postarr ) + public function examineImageInPost($data, $postarr) { //revision进来的请求不进行检测 if ($postarr['post_type'] !== 'post' || $postarr['ID'] === 0) { @@ -192,24 +235,73 @@ class TencentWordPressIMSActions return $data; } + $user = wp_get_current_user(); + $user_login = $user->data->user_login; + $user_nicename = $user->data->user_nicename; + $user_email = $user->data->user_email; + $user_role = $user->roles[0]; + $status = '发布失败'; + $type = 'url'; + $create_time = date('Y-m-d H:i:s', time()); foreach ($images as $index => $img) { - $response = $this->imageModeration($IMSOptions,'',trim($img,'\"')); + $response = $this->imageModeration($IMSOptions, '', trim($img, '\"')); //检测接口异常不进行报错 if (!($response instanceof ImageModerationResponse)) { break; } if ($response->getData()->EvilFlag !== 0 || $response->getData()->EvilType !== 100) { + // 命中记录入库 + $file_name = $img; + $this->insertIMSImageRecord($user_login, $user_nicename, $user_email, + $user_role, $status, $type, $file_name, $create_time); $num = $index + 1; - $error = new WP_Error( + $error = new WP_Error( 'img_url_examined_fail', - __( '文章内容包含的第'.$num.'张图片检测不通过,请删除后再提交') + __('文章内容包含的第' . $num . '张图片检测不通过,请删除后再提交') ); - wp_die($error,'文章包含的图片检测不通过.',['back_link'=>true]); + wp_die($error, '文章包含的图片检测不通过.', ['back_link' => true]); } } return $data; } + /** + * @param $user_login + * @param $user_nicename + * @param $user_email + * @param $user_role + * @param $type + * @param $content + * @param $post_title + * @param $evil_label + * @param $create_time + * @return mixed + */ + private function insertIMSImageRecord($user_login, $user_nicename, $user_email, $user_role, $status, $type, + $file_name, $create_time) + { + $wpdb = $GLOBALS['wpdb']; + $tableName = $wpdb->prefix . self::IMAGE_RECORD_TABLE_NAME; + $sql = "INSERT INTO `{$tableName}` (`user_login`, `user_nicename`, `user_email`, `user_role`, `status`, `type`, `file_name`, `create_time`) + VALUES (%s, %s, %s, %s, %s, %s, %s, %s);"; + return $wpdb->query($wpdb->prepare( + $sql, $user_login, $user_nicename, $user_email, $user_role, $status, $type, $file_name, $create_time + )); + } + + /** + * 卸载插件,删除检查记录 + */ + public static function deleteIMSImageRecordTable() + { + $wpdb = $GLOBALS['wpdb']; + $tableName = $wpdb->prefix . self::IMAGE_RECORD_TABLE_NAME; + if ($wpdb->get_var("SHOW TABLES LIKE '{$tableName}'") === $tableName) { + $sql = "DROP TABLE {$tableName};"; + $wpdb->query($sql); + } + } + /** * 腾讯云图片检测 @@ -219,7 +311,7 @@ class TencentWordPressIMSActions * @return Exception|ImageModerationResponse|TencentCloudSDKException * @throws Exception */ - private function imageModeration($IMSOptions,$imgContent = '',$imgUrl = '') + private function imageModeration($IMSOptions, $imgContent = '', $imgUrl = '') { try { if (empty($imgContent) && empty($imgUrl)) { @@ -234,28 +326,28 @@ class TencentWordPressIMSActions } else { $params['FileContent'] = base64_encode($imgContent); } - $req->fromJsonString(\GuzzleHttp\json_encode($params,JSON_UNESCAPED_UNICODE)); + $req->fromJsonString(\GuzzleHttp\json_encode($params, JSON_UNESCAPED_UNICODE)); $resp = $client->ImageModeration($req); return $resp; - } - catch(TencentCloudSDKException $e) { + } catch (TencentCloudSDKException $e) { return $e; } - } + } - /** - * 加载js脚本 - */ - public function loadMyScriptEnqueue() - { - wp_register_script('IMS_front_user_script', TENCENT_WORDPRESS_IMS_JS_DIR. 'front_user_script.js', array('jquery'),'2.1', true); + /** + * 加载js脚本 + */ + public function loadMyScriptEnqueue() + { + wp_register_script('IMS_front_user_script', TENCENT_WORDPRESS_IMS_JS_DIR . 'front_user_script.js', array('jquery'), '2.1', true); wp_enqueue_script('IMS_front_user_script'); - wp_register_script('IMS_back_admin_script', TENCENT_WORDPRESS_IMS_JS_DIR . 'back_admin_script.js', array('jquery'), '2.1',true); + wp_register_script('IMS_back_admin_script', TENCENT_WORDPRESS_IMS_JS_DIR . 'back_admin_script.js', array('jquery'), '2.1', true); wp_enqueue_script('IMS_back_admin_script'); - } + } + /** * 加载css * @param $hookSuffix @@ -263,7 +355,7 @@ class TencentWordPressIMSActions public function loadCSSEnqueue($hookSuffix) { //只在后台配置页引入 - if (strpos($hookSuffix,'page_TencentWordpressIMSSettingPage') !== false){ + if (strpos($hookSuffix, 'page_TencentWordpressIMSSettingPage') !== false) { wp_register_style('IMS_back_admin_css', TENCENT_WORDPRESS_IMS_CSS_DIR . 'bootstrap.min.css'); wp_enqueue_style('IMS_back_admin_css'); } @@ -276,33 +368,79 @@ class TencentWordPressIMSActions { require_once 'TencentWordpressIMSSettingPage.php'; TencentWordpressPluginsSettingActions::addTencentWordpressCommonSettingPage(); - add_submenu_page('TencentWordpressPluginsCommonSettingPage','图片内容安全','图片内容安全', 'manage_options', 'TencentWordpressIMSSettingPage', 'TencentWordpressIMSSettingPage'); + add_submenu_page('TencentWordpressPluginsCommonSettingPage', '图片内容安全', '图片内容安全', 'manage_options', 'TencentWordpressIMSSettingPage', 'TencentWordpressIMSSettingPage'); } - /** * 保存插件配置 */ public function updateIMSOptions() { try { - if ( !current_user_can( 'manage_options') ) { - wp_send_json_error(array('msg'=>'当前用户无权限')); + if (!current_user_can('manage_options')) { + wp_send_json_error(array('msg' => '当前用户无权限')); } $IMSOptions = new TencentWordpressIMSOptions(); $IMSOptions->setCustomKey($this->filterPostParam('customKey')); $IMSOptions->setSecretID($this->filterPostParam('secretID')); $IMSOptions->setSecretKey($this->filterPostParam('secretKey')); - $IMSOptions->setCheckUrlImg($this->filterPostParam('checkUrlImg',$IMSOptions::DO_NOT_CHECK)); + $IMSOptions->setCheckUrlImg($this->filterPostParam('checkUrlImg', $IMSOptions::DO_NOT_CHECK)); self::requirePluginCenterClass(); $staticData = self::getTencentCloudWordPressStaticData('save_config'); TencentWordpressPluginsSettingActions::sendUserExperienceInfo($staticData); - update_option(TENCENT_WORDPRESS_IMS_OPTIONS,$IMSOptions,true); - wp_send_json_success(array('msg'=>'保存成功')); + update_option(TENCENT_WORDPRESS_IMS_OPTIONS, $IMSOptions, true); + wp_send_json_success(array('msg' => '保存成功')); } catch (Exception $exception) { - wp_send_json_error(array('msg'=>$exception->getMessage())); + wp_send_json_error(array('msg' => $exception->getMessage())); + } + } + + public function getIMSImageRecords() + { + if (!current_user_can('manage_options')) { + wp_send_json_error(array('msg' => '当前用户无权限')); + } + $keyword = $this->filterPostParam('keyword'); + $page = $this->filterPostParam('page', 1); + $pageSize = $this->filterPostParam('page_size', 10); + if ($page < 1 || $page > 999999) { + $page = 1; + } + if ($pageSize < 1 || $pageSize > 50) { + $page = 10; + } + $pageSize = intval($pageSize); + $page = intval($page); + + $skip = ($page - 1) * $pageSize; + + if (!empty($keyword) && !is_string($keyword)) { + wp_send_json_error(array('msg' => '对象名称有误')); + } + $wpdb = $GLOBALS['wpdb']; + $tableName = $wpdb->prefix . self::IMAGE_RECORD_TABLE_NAME; + + if (empty($keyword)) { + $sql = "SELECT * FROM `{$tableName}` ORDER BY `id` DESC LIMIT {$skip},{$pageSize}"; + $result = $wpdb->get_results($wpdb->prepare($sql)); + //统计总条数 + $sql = "SELECT COUNT(`id`) as `count` FROM `{$tableName}`"; + $count = $wpdb->get_row($wpdb->prepare($sql)); + } else { + $sql = "SELECT * FROM `{$tableName}` WHERE `file_name` LIKE '%s' ORDER BY `id` DESC LIMIT {$skip},{$pageSize}"; + $result = $wpdb->get_results($wpdb->prepare($sql, '%' . $keyword . '%')); + $sql = "SELECT COUNT(`id`) as `count` FROM `{$tableName}` WHERE `file_name` LIKE '%s'"; + $count = $wpdb->get_row($wpdb->prepare($sql, '%' . $keyword . '%')); + } + $return = array('list' => $result, 'totalNum' => 0, 'totalPage' => 0, 'hasNext' => false); + if (!$result) { + wp_send_json_success($return); } + $return['totalNum'] = (int)$count->count; + $return['hasNext'] = $count->count > $pageSize * $page; + $return['totalPage'] = intval(ceil($count->count / $pageSize)); + wp_send_json_success($return); } /** @@ -313,7 +451,7 @@ class TencentWordPressIMSActions */ public function pluginSettingPageLinkButton($links, $file) { - if ( $file === TENCENT_WORDPRESS_IMS_BASENAME ) { + if ($file === TENCENT_WORDPRESS_IMS_BASENAME) { $links[] = '设置'; } return $links; diff --git a/tencentcloud-ims/TencentWordpressIMSSettingPage.php b/tencentcloud-ims/TencentWordpressIMSSettingPage.php index 5c41e4fb13b05157b7a233560ac4256e302b8658..9f3564d77af9fd07d4532274f42a550d7963ce5e 100644 --- a/tencentcloud-ims/TencentWordpressIMSSettingPage.php +++ b/tencentcloud-ims/TencentWordpressIMSSettingPage.php @@ -52,70 +52,134 @@ function TencentWordpressIMSSettingPage()
-