diff --git a/README.md b/README.md index 96938fd81bf58c0e8b072259848538160fecba5c..1e48ee0baaf288f9488d69fdffaa5f76ac16329d 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,8 @@ - GuzzleHttp 6.3.0+ (如果有其它插件引用了 GuzzleHttp 库并低于 6.3.0 版本会引起插件冲突) +- 支持PHP8, 兼容WordPress 5.8 + ## 1.插件介绍 > WordPress COS插件是一款腾讯云研发的,提供给WordPress站长使用的官方插件。实现网站静态媒体资源与腾讯云COS的互通,有效降低本地存储负载,提升用户访问网站媒体资源的体验。 @@ -13,7 +15,7 @@ | ---------- | ------------------------------------------------------------ | | 中文名称 | 腾讯云对象存储(COS)插件 | | 英文名称 | tencentcloud-cos | -| 最新版本 | 1.0.1 (2020.12.11) | +| 最新版本 | 1.0.2 (2021.8.20) | | 适用平台 | [WordPress](https://wordpress.org/) | | 适用产品 | [腾讯云对象存储(COS)](https://cloud.tencent.com/product/cos) | | GitHub项目 | [tencentcloud-wordpress-plugin-cos](https://github.com/Tencent-Cloud-Plugins/tencentcloud-wordpress-plugin-cos) | @@ -21,7 +23,6 @@ | 主创团队 | 腾讯云中小企业产品中心(SMB Product Center of Tencent Cloud) | - ## 2.功能特性 - 支持验证桶名是否有效 @@ -29,9 +30,9 @@ - 可配置是否保留本地备份-默认不备份 - 本地删除可同步删除腾讯云对象存储 COS 中的文件-默认同步删除 - 支持同步历史附件到 COS -- 支持上传文件自动重命名-默认支持 +- 支持上传文件自动重命名-支持三种命名格式 - API动态获取域名列表 - +- 本地调试日志功能 ## 3.安装指引 ### 3.1.部署方式一:通过GitHub部署安装 @@ -55,10 +56,12 @@ ![](./images/cos1.png) > 上图主要是配置COS插件的腾讯云参数,包括secretId、secretKey、所属地域、空间名称、是否自动重命名、不在本地保存、是否禁止生成缩略图、是否开启数据万象功能 - + ![](./images/cos2.png) > 上图中"附件同步"可同步WordPress媒体库中的全部文件到腾讯与的COS。 "一键替换"可替换网站内容中所有静态文件地址为腾讯云COS文件地址 +![](./images/cos3.png) +> 新增调试功能,开启后如果插件报错,错误信息能保留在本地日志文件中,方便排查问题 ### 4.2.名词解释 - **自定义密钥**:插件提供统一密钥管理,既可在多个腾讯云插件之间共享SecretId和SecretKey,也可为插件配置单独定义的腾讯云密钥。 - **SecretId**:在腾讯云云平台API密钥上申请的标识身份的 SecretId。详情参考[腾讯云文档](https://cloud.tencent.com/document/product) @@ -81,6 +84,8 @@ | gitee | [link](https://gitee.com/Tencent-Cloud-Plugins/tencentcloud-wordpress-plugin-cos) | | 插件中心 | [link](https://wordpress.org/plugins/tencentcloud-cos) | + + ## 6.FAQ ### 为什么打开插件媒体库同步后功能没有生效? @@ -92,6 +97,9 @@ ## 7.版本迭代记录 +### 2021.8.20 tencentcloud-wordpress-plugin-cos v1.0.2 +- 更新对象云存储插件上传文件自动重命名的功能,支持三种不同命名格式。 +- 新增本地调试日志功能 ### 2020.12.11 tencentcloud-wordpress-plugin-cos v1.0.1 - 支持在windows环境下运行 @@ -105,4 +113,10 @@ - API动态获取域名列表 ## 8.致谢 -- 该插件参考了wordpress插件[wpcos](https://github.com/lezaiyun/wpcos)及[wordpress-qcloud-cos](https://github.com/sy-records/wordpress-qcloud-cos)的实现方法,特此对其主创团队进行致谢。 \ No newline at end of file + +- 该插件参考了 WordPress 插件 [WPCOS](https://github.com/lezaiyun/wpcos) 及 [Sync QCloud COS](https://github.com/sy-records/wordpress-qcloud-cos) 的实现方法,特此对其主创团队进行致谢。 + + +本项目由腾讯云中小企业产品中心建设和维护,了解与该插件使用相关的更多信息,请访问[春雨文档中心](https://openapp.qq.com/docs/Wordpress/cos.html) + +请通过[咨询建议](https://da.do/y0rp) 向我们提交宝贵意见。 diff --git a/images/cos3.png b/images/cos3.png new file mode 100644 index 0000000000000000000000000000000000000000..354e3e2a54f37683c17a79e433f96f74e0aebae8 Binary files /dev/null and b/images/cos3.png differ diff --git a/tencentcloud-cos/assets/css/admin.css b/tencentcloud-cos/assets/css/admin.css index 325566eba3af7fa7d7e64749a5e4096521bc489c..7d54796ef4c6884992227655770f6acb3f6747b1 100644 --- a/tencentcloud-cos/assets/css/admin.css +++ b/tencentcloud-cos/assets/css/admin.css @@ -13,4 +13,4 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -.dashicons{vertical-align:middle;position:relative;right:30px}.lable-describle{vertical-align:0px}.select_region_style{width:150px}.setting_page_footer{text-align:center;line-height:50px}.image_process_style_customize{min-width:348px}.div_custom_switch_padding_top{padding-top:15px;padding-left:75px}.lable_padding_left{padding-left:30px} \ No newline at end of file +.dashicons{vertical-align:middle;position:relative;right:30px}.lable-describle{vertical-align:0px}.select_region_style{width:150px}.setting_page_footer{text-align:center;line-height:50px}.image_process_style_customize{min-width:348px; margin-bottom: 10px}.div_custom_switch_padding_top{padding-top:15px;padding-left:75px}.lable_padding_left{padding-left:30px} \ No newline at end of file diff --git a/tencentcloud-cos/assets/javascript/txwp_cos_setting.js b/tencentcloud-cos/assets/javascript/txwp_cos_setting.js index d5b25ca245abc343fc5cade265ebc1ad6cb6f03a..a97bd408b7bdfb29c6b346db4c5ad53411949607 100644 --- a/tencentcloud-cos/assets/javascript/txwp_cos_setting.js +++ b/tencentcloud-cos/assets/javascript/txwp_cos_setting.js @@ -16,14 +16,14 @@ jQuery(function ($) { var ajaxUrl = $("#wpcosform_cos_info_set").data("ajax-url"); - $("#customize_secret_information_checkbox_id").change(function() { + $("#customize_secret_information_checkbox_id").change(function () { var disabled = !($(this).is(':checked')); - $("#input_secret_id").attr('disabled',disabled); - $("#input_secret_key").attr('disabled',disabled); + $("#input_secret_id").attr('disabled', disabled); + $("#input_secret_key").attr('disabled', disabled); }); function change_type(input_element, span_eye) { - if(input_element[0].type === 'password') { + if (input_element[0].type === 'password') { input_element[0].type = 'text'; span_eye.addClass('dashicons-visibility').removeClass('shicons-hidden'); } else { @@ -63,8 +63,8 @@ jQuery(function ($) { $('#span_region')[0].innerHTML = "所属地域的值不能为空"; $('#span_region').show(); } else { - $("#select_region option").each(function (){ - if($(this)[0].value === $('#input_region')[0].value){ + $("#select_region option").each(function () { + if ($(this)[0].value === $('#input_region')[0].value) { $(this)[0].selected = true; } else { $(this)[0].selected = false; @@ -104,7 +104,7 @@ jQuery(function ($) { $.ajax({ type: "post", url: ajaxUrl, - dataType:"json", + dataType: "json", data: { action: "check_cos_bucket", region: region_name, @@ -112,8 +112,8 @@ jQuery(function ($) { secret_key: secret_key, bucket: bucket_name }, - success: function(response) { - if (response.success){ + success: function (response) { + if (response.success) { $('#span_bucket').hide(); } else { $('#span_bucket')[0].innerHTML = "空间名称错误,请检查参数是否正确!"; @@ -133,6 +133,31 @@ jQuery(function ($) { } }); + $('#auto_rename_style_customize_prefix').blur(function () { + var pwdRegex = /^[a-zA-Z0-9_\u4e00-\u9fa5]+$/; //判断字符串是否由数字,字母,下划线组成 + + if (!pwdRegex.test($('#auto_rename_style_customize_prefix')[0].value) + && $('#auto_rename_style_customize_prefix')[0].value) { + + $('#auto_rename_error_message')[0].innerHTML = "请输入由字母、数字、下划线或中文组成的字符串"; + $('#auto_rename_error_message').show(); + } else { + $('#auto_rename_error_message').hide(); + } + }); + $('#auto_rename_style_customize_postfix').blur(function () { + var pwdRegex = /^[a-zA-Z0-9_\u4e00-\u9fa5]+$/; //判断字符串是否为数字,字母,下划线组成 + + if (!pwdRegex.test($('#auto_rename_style_customize_postfix')[0].value) + && $('#auto_rename_style_customize_postfix')[0].value) { + + $('#auto_rename_error_message')[0].innerHTML = "请输入由字母、数字、下划线或中文组成的字符串"; + $('#auto_rename_error_message').show(); + } else { + $('#auto_rename_error_message').hide(); + } + }); + $('#button_save').click(function () { var region_name = $('#input_region')[0].value; var bucket_name = $('#input_bucket')[0].value; @@ -151,18 +176,32 @@ jQuery(function ($) { return false; } + if ($('#auto_rename_switch')[0].checked && $('#auto_rename_style_customize')[0].checked) { + var filename_prefix = $('#auto_rename_style_customize_prefix')[0].value; + var filename_postfix = $('#auto_rename_style_customize_postfix')[0].value; + var pwdRegex = /^[a-zA-Z0-9_\u4e00-\u9fa5]+$/; //判断字符串是否由数字,字母,下划线组成 + if (filename_prefix && !pwdRegex.test(filename_prefix)) { + alert("自定义文件名前缀是由字母、数字、下划线或中文组成的字符串!"); + return false; + } + + if (filename_postfix && !pwdRegex.test(filename_postfix)) { + alert("自定义文件名后缀是由字母、数字、下划线或中文组成的字符串!"); + return false; + } + } $.ajax({ type: "post", url: ajaxUrl, - dataType:"json", + dataType: "json", data: { action: "save_cos_options", formdata: $('form#wpcosform_cos_info_set').serialize() }, - success: function(response) { - if (response.success){ + success: function (response) { + if (response.success) { $('#span_button_save')[0].innerHTML = "保存成功!"; } else { @@ -179,12 +218,12 @@ jQuery(function ($) { $.ajax({ type: "post", url: ajaxUrl, - dataType:"json", + dataType: "json", data: { action: "replace_localurl_to_cosurl" }, - success: function(response) { - if (response.success){ + success: function (response) { + if (response.success) { $('#span_cos_info_replace')[0].innerHTML = "成功替换" + response.data.replace + "个COS地址!"; $('#span_cos_info_replace').show().delay(5000).fadeOut(); } else { @@ -199,13 +238,13 @@ jQuery(function ($) { $.ajax({ type: "post", url: ajaxUrl, - dataType:"json", + dataType: "json", data: { action: "sync_attachment_to_cos" }, - success: function(response) { - if (response.success){ - $('#span_attachment_sync')[0].innerHTML = "成功同步"+ response.data.replace+ "个附件!"; + success: function (response) { + if (response.success) { + $('#span_attachment_sync')[0].innerHTML = "成功同步" + response.data.replace + "个附件!"; $('#span_attachment_sync').show().delay(5000).fadeOut(); } else { $('#span_attachment_sync')[0].innerHTML = "同步失败,请检查腾讯云COS配置信息、本地文件路径和cos地址路径是否正确!"; @@ -215,6 +254,23 @@ jQuery(function ($) { }); }); + $('#button_delete_logfile').click(function () { + $.ajax({ + type: "post", + url: ajaxUrl, + dataType: "json", + data: { + action: "delete_cos_logfile" + }, + success: function (response) { + if (response.success) { + $('#span_delete_logfile')[0].innerHTML = "删除成功!"; + $('#span_delete_logfile').show().delay(5000).fadeOut(); + } + } + }); + }); + $('#image_process_switch').change(function () { if ($('#image_process_switch')[0].checked) { $('#div_img_process_code').show(); @@ -223,6 +279,22 @@ jQuery(function ($) { } }); + $('#automatic_logging_switch').change(function () { + if ($('#automatic_logging_switch')[0].checked) { + $('#div_delete_filelog_code').show(); + } else { + $('#div_delete_filelog_code').hide(); + } + }); + + $('#auto_rename_switch').change(function () { + if ($('#auto_rename_switch')[0].checked) { + $('#div_auto_rename').show(); + } else { + $('#div_auto_rename').hide(); + } + }); + $('#img_process_style_default').change(function () { if ($('#img_process_style_default')[0].checked) { $('#img_process_style_customize_input')[0].disabled = true; @@ -236,6 +308,31 @@ jQuery(function ($) { } }); + $('#auto_rename_style_default1').change(function () { + if ($('#auto_rename_style_default1')[0].checked) { + $('#auto_rename_style_customize_prefix')[0].disabled = true; + $('#auto_rename_style_customize_prefix')[0].value = ''; + $('#auto_rename_style_customize_postfix')[0].disabled = true; + $('#auto_rename_style_customize_postfix')[0].value = ''; + } + }); + + $('#auto_rename_style_default2').change(function () { + if ($('#auto_rename_style_default2')[0].checked) { + $('#auto_rename_style_customize_prefix')[0].disabled = true; + $('#auto_rename_style_customize_prefix')[0].value = ''; + $('#auto_rename_style_customize_postfix')[0].disabled = true; + $('#auto_rename_style_customize_postfix')[0].value = ''; + } + }); + + $('#auto_rename_style_customize').change(function () { + if ($('#auto_rename_style_customize')[0].checked) { + $('#auto_rename_style_customize_postfix')[0].disabled = false; + $('#auto_rename_style_customize_prefix')[0].disabled = false; + } + }); + $('#cos_attachment_sync_link').click(function () { $('#cos_attachment_sync_desc').toggle(); }); diff --git a/tencentcloud-cos/class-tencent-cloud-cos-base.php b/tencentcloud-cos/class-tencent-cloud-cos-base.php index 5795618734613b23189774abfb133d2375576bff..e9b892c2632f21f226ee5fed1b50ed82a2e657a1 100644 --- a/tencentcloud-cos/class-tencent-cloud-cos-base.php +++ b/tencentcloud-cos/class-tencent-cloud-cos-base.php @@ -1,4 +1,5 @@ getMessage(); - $statusCode = $ex->getStatusCode(); - echo '

ErrorCode:' . $statusCode . ',ErrorMessage:' . $errorMessage . '

'; + CosDebugLog::writeDebugLog('error', 'msg : ' . $ex->getMessage(), __FILE__, __LINE__); + return false; } - return false; } /** @@ -206,11 +209,12 @@ class TencentWordpressCosBase { self::deleteLocalFile($file_local_path); } return true; + } else { + CosDebugLog::writeDebugLog('warring', 'msg : ' . $file_local_path . ' The file path is empty', __FILE__, __LINE__); } } catch (\Exception $e) { - $errorMessage = $e->getMessage(); - $statusCode = $e->getStatusCode(); - echo '

ErrorCode:' . $statusCode . ',ErrorMessage:' . $errorMessage . '

'; + CosDebugLog::writeDebugLog('error', 'msg : ' . $e->getMessage(), __FILE__, __LINE__); + return false; } } @@ -235,8 +239,8 @@ class TencentWordpressCosBase { return false; } } catch (\Exception $e) { - $errorMessage = $e->getMessage(); - $statusCode = $e->getStatusCode(); + CosDebugLog::writeDebugLog('error', 'msg : ' . $e->getMessage(), __FILE__, __LINE__); + return false; } } @@ -271,9 +275,8 @@ class TencentWordpressCosBase { } } } catch (ServiceResponseException $e) { - $errorMessage = $e->getMessage(); - $statusCode = $e->getStatusCode(); - echo '

ErrorCode:' . $statusCode . ',ErrorMessage:' . $errorMessage . '

'; + CosDebugLog::writeDebugLog('error', 'msg : ' . $e->getMessage(), __FILE__, __LINE__); + return false; } } diff --git a/tencentcloud-cos/class-tencent-cloud-cos.php b/tencentcloud-cos/class-tencent-cloud-cos.php index e659e1beab20f6c84ff649a51cba8c742b0cacd6..97e9e926accb1681b2d5eacada972e52b8718663 100644 --- a/tencentcloud-cos/class-tencent-cloud-cos.php +++ b/tencentcloud-cos/class-tencent-cloud-cos.php @@ -16,7 +16,9 @@ */ require_once TENCENT_WORDPRESS_PLUGINS_COMMON_DIR . 'TencentWordpressPluginsSettingActions.php'; require_once TENCENT_WORDPRESS_COS_PLUGIN_DIR . 'class-tencent-cloud-cos-base.php'; -class TencentWordpressCOS extends TencentWordpressCosBase { + +class TencentWordpressCOS extends TencentWordpressCosBase +{ private static $initiated = false; private static $version = ''; @@ -91,6 +93,10 @@ class TencentWordpressCOS extends TencentWordpressCosBase { // 保存COS插件配置信息 add_action('wp_ajax_save_cos_options', array('TencentWordpressCOS', 'tcwpcosSaveOptions')); + + // 清除插件日志 + add_action('wp_ajax_delete_cos_logfile', array('TencentWordpressCOS', 'tcwpcosDeleteLogFile')); + } /** @@ -106,7 +112,7 @@ class TencentWordpressCOS extends TencentWordpressCosBase { $static_data['action'] = $action; $static_data['plugin_type'] = self::$plugin_type; $static_data['data'] = array( - 'site_id' => $site_id, + 'site_id' => $site_id, 'site_url' => $site_url, 'site_app' => $site_app ); @@ -190,6 +196,8 @@ class TencentWordpressCOS extends TencentWordpressCosBase { //发送用户体验数据 $static_data = self::getTencentCloudWordPressStaticData('activate'); TencentWordpressPluginsSettingActions::sendUserExperienceInfo($static_data); + + CosDebugLog::writeDebugLog('notice', 'msg : enable cos plugin', __FILE__, __LINE__); } /** @@ -214,6 +222,8 @@ class TencentWordpressCOS extends TencentWordpressCosBase { //发送用户体验数据 $static_data = self::getTencentCloudWordPressStaticData('deactivate'); TencentWordpressPluginsSettingActions::sendUserExperienceInfo($static_data); + + CosDebugLog::writeDebugLog('notice', 'msg : disable cos plugin', __FILE__, __LINE__); } /** @@ -257,9 +267,26 @@ class TencentWordpressCOS extends TencentWordpressCosBase { */ public static function tcwpcosSanitizeFileName($filename) { + if (!$filename) { + CosDebugLog::writeDebugLog('error', 'msg : file not exist!', __FILE__, __LINE__); + } $tcwpcos_options = self::getCosOptons(); - if ($tcwpcos_options['opt']['auto_rename']) { - return date("YmdHis") . "" . mt_rand(100, 999) . "." . pathinfo($filename, PATHINFO_EXTENSION); + if (isset($tcwpcos_options['opt']['auto_rename_config']) + && $tcwpcos_options['opt']['auto_rename_config']['auto_rename_switch'] === 'on') { + if ($tcwpcos_options['opt']['auto_rename_config']['auto_rename_style_choice'] === '0') { + // 默认(日期+随机串) + return date("YmdHis") . mt_rand(100, 999) + . pathinfo($filename, PATHINFO_EXTENSION); + } elseif ($tcwpcos_options['opt']['auto_rename_config']['auto_rename_style_choice'] === '1') { + // 格式一(日期+文件名+随机串) + return date("YmdHis") . pathinfo($filename)['filename'] . mt_rand(100, 999) . "." + . pathinfo($filename, PATHINFO_EXTENSION); + } elseif ($tcwpcos_options['opt']['auto_rename_config']['auto_rename_style_choice'] === '2') { + // 格式二(自定义前缀+日期+文件名称+自定义后缀) + return $tcwpcos_options['opt']['auto_rename_config']['auto_rename_customize_prefix'] . + date("YmdHis") . pathinfo($filename)['filename'] . $tcwpcos_options['opt']['auto_rename_config']['auto_rename_customize_postfix'] + . "." . pathinfo($filename, PATHINFO_EXTENSION); + } } else { return $filename; } @@ -288,7 +315,6 @@ class TencentWordpressCOS extends TencentWordpressCosBase { $tcwpcos_options = self::getCosOptons(); self::uploadFileToCos($key, $local_path, $tcwpcos_options['no_local_file']); } - return $upload; } @@ -360,6 +386,10 @@ class TencentWordpressCOS extends TencentWordpressCosBase { */ public static function tcwpcosUniqueFilename($filename) { + if (!$filename) { + CosDebugLog::writeDebugLog('error', 'msg : file not exist', __FILE__, __LINE__); + } + $ext = '.' . pathinfo($filename, PATHINFO_EXTENSION); $number = ''; while (self::isCosRemoteFileExists(wp_get_upload_dir()['subdir'] . "/$filename")) { @@ -375,7 +405,7 @@ class TencentWordpressCOS extends TencentWordpressCosBase { } /** - * 上传cos中的附件 + * 删除cos中的附件 * @param $post_id */ public static function tcwpcosDeleteRemoteAttachment($post_id) @@ -416,14 +446,14 @@ class TencentWordpressCOS extends TencentWordpressCosBase { if (!empty($deleteObjects)) { $cosClient = self::getCosClient(); - $tcwpcos_options =self::getCosOptons(); + $tcwpcos_options = self::getCosOptons(); try { $cosClient->deleteObjects(array( 'Bucket' => esc_attr($tcwpcos_options['bucket']), 'Objects' => $deleteObjects, )); } catch (Exception $ex) { - echo $ex; + CosDebugLog::writeDebugLog('error', 'msg : ' . $ex->getMessage(), __FILE__, __LINE__); } } } @@ -475,18 +505,15 @@ class TencentWordpressCOS extends TencentWordpressCosBase { */ public static function tcwpcosAddSettingPage() { - if ( !current_user_can( 'manage_options' ) ) { - wp_die( __( 'Sorry, you are not allowed to manage options for this site.' ) ); - } TencentWordpressPluginsSettingActions::addTencentWordpressCommonSettingPage(); - $pagehook = add_submenu_page('TencentWordpressPluginsCommonSettingPage','对象存储','对象存储', 'manage_options', 'tencent_wordpress_plugin_cos', array('TencentWordpressCOS', 'tcwpcosSettingPage')); - add_action( 'admin_print_styles-'.$pagehook, array('TencentWordpressCOS', 'tcwpcosLoadCssForSettingPage')); + $pagehook = add_submenu_page('TencentWordpressPluginsCommonSettingPage', '对象存储', '对象存储', 'manage_options', 'tencent_wordpress_plugin_cos', array('TencentWordpressCOS', 'tcwpcosSettingPage')); + add_action('admin_print_styles-' . $pagehook, array('TencentWordpressCOS', 'tcwpcosLoadCssForSettingPage')); } public static function tcwpcosLoadCssForSettingPage() { - wp_enqueue_style('tencent_cloud_cos_bootstrap_css',TENCENT_WORDPRESS_COS_PLUGIN_CSS_URL.'bootstrap.min.css'); - wp_enqueue_style('tencent_cloud_cos_admin_css',TENCENT_WORDPRESS_COS_PLUGIN_CSS_URL.'admin.css'); + wp_enqueue_style('tencent_cloud_cos_bootstrap_css', TENCENT_WORDPRESS_COS_PLUGIN_CSS_URL . 'bootstrap.min.css'); + wp_enqueue_style('tencent_cloud_cos_admin_css', TENCENT_WORDPRESS_COS_PLUGIN_CSS_URL . 'admin.css'); } /** @@ -508,7 +535,28 @@ class TencentWordpressCOS extends TencentWordpressCosBase { unset($tcwpcos_options['opt']['img_process']['switch']); } - $tcwpcos_options['opt']['auto_rename'] = isset($options['auto_rename']) ? 1 : 0; + if (isset($options['auto_rename_switch']) && $options['auto_rename_switch'] === 'on') { + $tcwpcos_options['opt']['auto_rename_config']['auto_rename_switch'] = 'on'; + + if (isset($options['auto_rename_style_choice']) && $options['auto_rename_style_choice'] == '2') { + $tcwpcos_options['opt']['auto_rename_config']['auto_rename_style_choice'] = $options['auto_rename_style_choice']; + $tcwpcos_options['opt']['auto_rename_config']['auto_rename_customize_prefix'] = $options['auto_rename_customize_prefix']; + + $tcwpcos_options['opt']['auto_rename_config']['auto_rename_customize_postfix'] = $options['auto_rename_customize_postfix']; + } else { + $tcwpcos_options['opt']['auto_rename_config']['auto_rename_style_choice'] = $options['auto_rename_style_choice']; + } + + } else { + unset($tcwpcos_options['opt']['auto_rename_config']['auto_rename_switch']); + } + + + if (isset($options['automatic_logging']) && $options['automatic_logging'] == 'on') { + $tcwpcos_options['opt']['automatic_logging'] = 'on'; + } else { + unset($tcwpcos_options['opt']['automatic_logging']); + } return $tcwpcos_options['opt']; } @@ -565,9 +613,6 @@ class TencentWordpressCOS extends TencentWordpressCosBase { */ public static function tcwpcosSettingPage() { - if (!current_user_can('manage_options')) { - wp_die(__('Sorry, you are not allowed to manage options for this site.')); - } include TENCENT_WORDPRESS_COS_PLUGIN_DIR . 'tencentcloud-plugin-cos-setting-page.php'; } @@ -588,8 +633,10 @@ class TencentWordpressCOS extends TencentWordpressCosBase { $region = sanitize_text_field($_POST['region']); $bucketName = sanitize_text_field($_POST['bucket']); $tcwpcos_options = self::getCosOptons(); - if (isset($tcwpcos_options) && isset($tcwpcos_options['customize_secret']) && $tcwpcos_options['customize_secret'] === false) { - $tcwp_common_options = get_option('tencent_wordpress_common_options'); + $tcwp_common_options = get_option('tencent_wordpress_common_options'); + if (isset($tcwpcos_options) && isset($tcwpcos_options['customize_secret']) && + $tcwpcos_options['customize_secret'] === false && $tcwp_common_options['site_sec_on'] === true) { + $secretId = sanitize_text_field($tcwp_common_options['secret_id']); $secretKey = sanitize_text_field($tcwp_common_options['secret_key']); } else { @@ -603,11 +650,18 @@ class TencentWordpressCOS extends TencentWordpressCosBase { 'bucket' => $bucketName ); - if (self::checkCosBucket($options)) { - wp_send_json_success(); - } else { + try { + if (self::checkCosBucket($options)) { + wp_send_json_success(); + } else { + CosDebugLog::writeDebugLog('error', 'msg : params error', __FILE__, __LINE__); + wp_send_json_error(); + } + } catch (\Exception $e) { + CosDebugLog::writeDebugLog('error', 'msg : ' . $e->getMessage(), __FILE__, __LINE__); wp_send_json_error(); } + } /** @@ -650,7 +704,7 @@ class TencentWordpressCOS extends TencentWordpressCosBase { $i++; } } - if ($i >= 0) { + if ($i >= 0) { wp_send_json_success(array('replace' => $i)); } wp_send_json_error(); @@ -662,20 +716,19 @@ class TencentWordpressCOS extends TencentWordpressCosBase { public static function tcwpcosSaveOptions() { if (empty($_POST) || empty($_POST['formdata'])) { + CosDebugLog::writeDebugLog('error', 'msg : Parameter error', __FILE__, __LINE__); wp_send_json_error(array('errMsg' => '参数错误')); } parse_str($_POST['formdata'], $output); + $options = array( - 'region' => sanitize_text_field($output['region']), + 'region' => sanitize_text_field($output['region']), 'regionname' => sanitize_text_field($output['regionname']), - 'bucket' => sanitize_text_field($output['bucket']), + 'bucket' => sanitize_text_field($output['bucket']), 'upload_url_path' => sanitize_text_field($output['upload_url_path']) ); - if (isset($output['auto_rename'])) { - $options['auto_rename'] = sanitize_text_field($output['auto_rename']); - } if (isset($output['secret_id'])) { $options['secret_id'] = sanitize_text_field($output['secret_id']); @@ -709,6 +762,37 @@ class TencentWordpressCOS extends TencentWordpressCosBase { $options['img_process_style_customize'] = sanitize_text_field($output['img_process_style_customize']); } + if (isset($output['auto_rename'])) { + $options['auto_rename'] = sanitize_text_field($output['auto_rename']); + } + + if (isset($output['auto_rename_switch'])) { + $options['auto_rename_switch'] = sanitize_text_field($output['auto_rename_switch']); + } + + if (isset($output['auto_rename_style_choice'])) { + $options['auto_rename_style_choice'] = sanitize_text_field($output['auto_rename_style_choice']); + } + + if (isset($output['auto_rename_style_customize'])) { + $options['auto_rename_style_customize'] = sanitize_text_field($output['auto_rename_style_customize']); + } + + if (isset($output['auto_rename_customize_prefix'])) { + $options['auto_rename_customize_prefix'] = sanitize_text_field($output['auto_rename_customize_prefix']); + } + if (isset($output['auto_rename_customize_postfix'])) { + $options['auto_rename_customize_postfix'] = sanitize_text_field($output['auto_rename_customize_postfix']); + } + + if (isset($output['automatic_logging'])) { + $options['automatic_logging'] = sanitize_text_field($output['automatic_logging']); + } + + if (isset($output['automatic_logging_switch'])) { + $options['automatic_logging_switch'] = sanitize_text_field($output['automatic_logging_switch']); + } + $tcwpcos_options = self::updateCosOptions($options); $tcwpcos_options['activation'] = true; @@ -721,4 +805,65 @@ class TencentWordpressCOS extends TencentWordpressCosBase { TencentWordpressPluginsSettingActions::sendUserExperienceInfo($static_data); wp_send_json_success(); } + + /** + * 保存配置参数 + */ + public static function tcwpcosDeleteLogFile() + { + if (!file_exists(TENCENT_WORDPRESS_COS_LOGS)) { + wp_send_json_success(); + } + + self::removeDir(TENCENT_WORDPRESS_COS_LOGS); + wp_send_json_success(); + } + + /** + * 迭代删除目录及目录中的自文件 + * + * @param string $dir + * @access public + * @return bool + * @throws Exception + */ + public static function removeDir($dir) + { + if (empty($dir)) { + return true; + } + + $dir = realpath($dir) . '/'; + if ($dir == '/') { + CosDebugLog::writeDebugLog('notice', 'msg : can not remove root dir', __FILE__, __LINE__); + return false; + } + + if (!is_writable($dir)) { + CosDebugLog::writeDebugLog('notice', 'msg : no delete permission ', __FILE__, __LINE__); + return false; + } + + if (!is_dir($dir)) { + return true; + } + + $entries = scandir($dir); + foreach ($entries as $entry) { + if ($entry == '.' or $entry == '..') + continue; + + $fullEntry = $dir . $entry; + if (is_file($fullEntry)) { + @unlink($fullEntry); + } else { + return self::removeDir($fullEntry); + } + } + if (!@rmdir($dir)) { + CosDebugLog::writeDebugLog('notice', 'msg : remove log dir failed', __FILE__, __LINE__); + return false; + } + return true; + } } diff --git a/tencentcloud-cos/readme.txt b/tencentcloud-cos/readme.txt index 7040b93388a8faa5613853fa06f1d5a45df9174f..291d93153e7e806adac6548e6a325fe818badf9c 100644 --- a/tencentcloud-cos/readme.txt +++ b/tencentcloud-cos/readme.txt @@ -2,10 +2,10 @@ Contributors: 腾讯云中小企业产品中心(SMB Product Center of Tencent Cloud) Donate link: https://cloud.tencent.com/ Tags:腾讯云wordpress, COS,腾讯云对象存储,腾讯云存储分离,腾讯云存储 -Requires at least: 5.0 -Tested up to: 5.4.1 -Requires PHP: 5.6 -Stable tag: 1.0.1 +Requires at least: 5.5 +Tested up to: 5.8 +Requires PHP: 8 +Stable tag: 1.0.2 License: Apache 2.0 License URI: http://www.apache.org/licenses/LICENSE-2.0.txt @@ -37,6 +37,13 @@ License URI: http://www.apache.org/licenses/LICENSE-2.0.txt 1. screenshot-1.png == Changelog == += 1.0.2 = +* 1、新增本地调试日志 +* 2、支持自定义重命名规则 + += 1.0.1 = +* 1、支持在windows环境下运行 + = 1.0.0 = * 1、支持验证桶名是否有效; * 2、可配置是否上传缩略图; @@ -46,6 +53,3 @@ License URI: http://www.apache.org/licenses/LICENSE-2.0.txt * 6、支持腾讯云数据万象 CI 图片处理 * 7、支持上传文件自动重命名 * 8、支持同步历史附件到 COS - -= 1.0.1 = -* 1、支持在windows环境下运行 \ No newline at end of file diff --git a/tencentcloud-cos/tencentcloud-cos-debuger.php b/tencentcloud-cos/tencentcloud-cos-debuger.php new file mode 100644 index 0000000000000000000000000000000000000000..f4624bbba25f9dc519e4b8c1fb270c74645cb2df --- /dev/null +++ b/tencentcloud-cos/tencentcloud-cos-debuger.php @@ -0,0 +1,157 @@ +_file_ext = 'log'; + self::$instance->_log_path = TENCENT_WORDPRESS_COS_LOGS; + self::$instance->_file_permissions = 0644; + self::$instance->_date_fmt = 'Y-m-d H:i:s'; + self::$instance->_func_overload = false; + self::$instance->_enable = true; + } + } + + + /** + * 将消息输出到指定的文件 + * @param $level + * @param string $msg 消息内容 + * @param string $file 日志文件名称,默认是 qcloud_rain_php.log + * @return bool + * @throws Exception + */ + public static function writeDebugLog($level, $msg, $file_path = '', $line = '') + { + self::_init(); + $tcwpcos_options = TencentWordpressCosBase::getCosOptons(); + if (isset($tcwpcos_options, $tcwpcos_options['opt'], $tcwpcos_options['opt']['automatic_logging']) + && ($tcwpcos_options['opt']['automatic_logging']) === 'on') { + + if (self::$instance->_enable === false) { + return FALSE; + } + if (!is_dir(self::$instance->_log_path)) { + @mkdir(self::$instance->_log_path, 0777); + } + $level = strtoupper($level); + $log_file_path = self::$instance->_log_path . '/log-' . date('Y-m-d') . '.' . self::$instance->_file_ext; + + if (!file_exists($log_file_path)) { + $newfile = TRUE; + } + + if (!$fp = @fopen($log_file_path, 'ab')) { + return FALSE; + } + + flock($fp, LOCK_EX); + if (strpos(self::$instance->_date_fmt, 'u') !== FALSE) { + $microtime_full = microtime(TRUE); + $microtime_short = sprintf("%06d", ($microtime_full - floor($microtime_full)) * 1000000); + $date = new DateTime(date('Y-m-d H:i:s.' . $microtime_short, $microtime_full)); + $date = $date->format(self::$instance->_date_fmt); + } else { + $date = date(self::$instance->_date_fmt); + } + + $message = self::$instance->_format_line($level, $date, $msg, $file_path, $line); + $result = 0; + for ($written = 0, $length = self::$instance->strlen($message); $written < $length; $written += $result) { + if (($result = fwrite($fp, self::$instance->substr($message, $written))) === FALSE) { + break; + } + } + + flock($fp, LOCK_UN); + fclose($fp); + + if (isset($newfile) && $newfile === TRUE) { + chmod($log_file_path, self::$instance->_file_permissions); + } + + return is_int($result); + } + + } + + /** + * 格式化输出字符串 + * @param $level + * @param $date + * @param $message + * @return string + */ + private function _format_line($level, $date, $message, $file_path, $line) + { + $format_line = $level . ', ' . $date . ', ' . $message; + if (isset($file_path) && !empty($file_path)) { + $format_line .= ", filepath:" . $file_path; + } + + if (isset($line) && !empty($line)) { + $format_line .= ", line:" . $line; + } + + $format_line .= "\n"; + return $format_line; + } + + /** + * 获取字符串长度,支持中文 + * @param $str + * @return false|int + */ + private static function strlen($str) + { + return (self::$instance->_func_overload) + ? mb_strlen($str, '8bit') + : strlen($str); + } + + /** + * 获取子字符串,支持中文 + * @param $str + * @param $start + * @param null $length + * @return false|string + */ + private static function substr($str, $start, $length = NULL) + { + if (self::$instance->_func_overload) { + isset($length) or $length = ($start >= 0 ? self::strlen($str) - $start : -$start); + return mb_substr($str, $start, $length, '8bit'); + } + + return isset($length) + ? substr($str, $start, $length) + : substr($str, $start); + } + } +} diff --git a/tencentcloud-cos/tencentcloud-cos.php b/tencentcloud-cos/tencentcloud-cos.php index dfb235325d50d555966187774505e31ae5c3dd88..3fb9903d0932a2ea615337f0382bc8aedbfffe4d 100644 --- a/tencentcloud-cos/tencentcloud-cos.php +++ b/tencentcloud-cos/tencentcloud-cos.php @@ -3,7 +3,7 @@ * Plugin Name: tencentcloud-cos * Plugin URI: https://openapp.qq.com/ * Description: 通过腾讯云对象存储服务使网站中静态文件无缝同步腾讯云对象存储COS,提升网站内容访问速度,降低本地存储开销。 - * Version: 1.0.1 + * Version: 1.0.2 * Author: 腾讯云 * Author URI: https://cloud.tencent.com/ * @@ -27,8 +27,10 @@ if (!defined('ABSPATH')) { die('We\'re sorry, but you can not directly access this file.'); } -defined('TENCENT_WORDPRESS_COS_VERSION') or define('TENCENT_WORDPRESS_COS_VERSION', '1.0.1'); +defined('TENCENT_WORDPRESS_COS_VERSION') or define('TENCENT_WORDPRESS_COS_VERSION', '1.0.2'); defined('TENCENT_WORDPRESS_COS_PLUGIN_DIR') or define('TENCENT_WORDPRESS_COS_PLUGIN_DIR', plugin_dir_path(__FILE__)); +defined('TENCENT_WORDPRESS_COS_LOGS') or define('TENCENT_WORDPRESS_COS_LOGS', plugin_dir_path(__FILE__) . 'logs'); + defined('TENCENT_WORDPRESS_PLUGINS_COMMON_DIR') or define('TENCENT_WORDPRESS_PLUGINS_COMMON_DIR', TENCENT_WORDPRESS_COS_PLUGIN_DIR . 'common' . DIRECTORY_SEPARATOR); defined('TENCENT_WORDPRESS_COS_PLUGIN_INC_DIR') or define('TENCENT_WORDPRESS_COS_PLUGIN_INC_DIR', TENCENT_WORDPRESS_COS_PLUGIN_DIR . 'includes' . DIRECTORY_SEPARATOR); @@ -54,6 +56,7 @@ defined('TENCENT_WORDPRESS_COS_RELATIVE_PATH') or define('TENCENT_WORDPRESS_COS_ require_once TENCENT_WORDPRESS_COS_PLUGIN_VENDER_DIR . 'autoload.php'; require_once TENCENT_WORDPRESS_COS_PLUGIN_DIR . 'class-tencent-cloud-cos.php'; +require(TENCENT_WORDPRESS_COS_PLUGIN_DIR . "tencentcloud-cos-debuger.php"); register_activation_hook(__FILE__, array('TencentWordpressCOS', 'tcwpcosActivatePlugin')); register_deactivation_hook(__FILE__, array('TencentWordpressCOS', 'tcwpcosDeactivePlugin')); diff --git a/tencentcloud-cos/tencentcloud-plugin-cos-setting-page.php b/tencentcloud-cos/tencentcloud-plugin-cos-setting-page.php index 34eb0efee89bc27dafa0fdf6e7dfbd10f6005660..ac77c211b117b3d9a79f8f5d99ef11367df0297a 100644 --- a/tencentcloud-cos/tencentcloud-plugin-cos-setting-page.php +++ b/tencentcloud-cos/tencentcloud-plugin-cos-setting-page.php @@ -18,9 +18,11 @@ if (!defined('ABSPATH')) { die('We\'re sorry, but you can not directly access this file.'); } + $tcwpcos_options = get_option(TENCENT_WORDPRESS_COS_OPTIONS); $upload_url_path = get_option(TENCENT_WORDPRESS_COS_UPLOAD_URL_PATH); $ajax_url = admin_url(TENCENT_WORDPRESS_COS_ADMIN_AJAX); + ?> @@ -37,12 +39,15 @@ $ajax_url = admin_url(TENCENT_WORDPRESS_COS_ADMIN_AJAX);
-
+
- +
-
- - value=" "> + value=""> @@ -73,14 +81,17 @@ $ajax_url = admin_url(TENCENT_WORDPRESS_COS_ADMIN_AJAX);
- - value=""> + value="">
@@ -91,31 +102,97 @@ $ajax_url = admin_url(TENCENT_WORDPRESS_COS_ADMIN_AJAX);
- +
@@ -126,19 +203,26 @@ $ajax_url = admin_url(TENCENT_WORDPRESS_COS_ADMIN_AJAX);
- +
-

首先到腾讯云控制台新建bucket存储桶或填写腾讯云"COS"以创建的bucket

+

首先到腾讯云控制台新建bucket存储桶或填写腾讯云"COS"以创建的bucket +

示范:wordpress-xxxxxx

- +

@@ -150,26 +234,114 @@ $ajax_url = admin_url(TENCENT_WORDPRESS_COS_ADMIN_AJAX);
- +
- > - +
+
+
+

+ + +
+ + +
+ + +
+ + + > +
+ + > +

+ +

+

+
+
- +
-
- +
-
- +
- > + 了解详情
@@ -228,7 +405,8 @@ $ajax_url = admin_url(TENCENT_WORDPRESS_COS_ADMIN_AJAX); } ?>;">
+
+ +
+ + > + +
+
+ +
+
+

+ +

+ +
+
+ +
@@ -272,14 +491,20 @@ $ajax_url = admin_url(TENCENT_WORDPRESS_COS_ADMIN_AJAX);
-
+
- +
-

同步媒体库中的全部文件到腾讯云COS,

-