完成社区源列表、自定义源 本次提交修改较多,难免存在BUG,不建议用于生产环节

This commit is contained in:
sunxiyuan 2020-03-12 17:14:13 +08:00
parent 29785f6992
commit 6343b1dfbc
5 changed files with 383 additions and 66 deletions

55
api.php Normal file
View file

@ -0,0 +1,55 @@
<?php
/*
* API接口
* Author: 孙锡源
* Version: 2.0.0
* Author URI:https://www.ibadboy.net/
* License: GPLv3 or later
* License URI: http://www.gnu.org/licenses/gpl-3.0.html
*/
require_once($_SERVER['DOCUMENT_ROOT'] . '/wp-config.php');
require_once($_SERVER['DOCUMENT_ROOT'] . '/wp-includes/option.php');
require_once($_SERVER['DOCUMENT_ROOT'] . '/wp-includes/capabilities.php');
header('Content-Type:application/json; charset=utf-8');
if (current_user_can('manage_options')) {
if (array_key_exists('get_config', $_GET)) {
success('', get_option('wp_china_yes_options'));
}
if (( ! array_key_exists('api_server', $_POST) && ! array_key_exists('download_server', $_POST)) ||
( ! array_key_exists('community', $_POST) && ! array_key_exists('custom_api_server', $_POST) && ! array_key_exists('custom_download_server', $_POST))) {
error('参数错误', - 1);
}
$options = array();
$options['community'] = sanitize_text_field(trim($_POST['community']));
$options['custom_api_server'] = sanitize_text_field(trim($_POST['custom_api_server']));
$options['custom_download_server'] = sanitize_text_field(trim($_POST['custom_download_server']));
$options["api_server"] = sanitize_text_field(trim($_POST['api_server']));
$options["download_server"] = sanitize_text_field(trim($_POST['download_server']));
update_option("wp_china_yes_options", $options);
success('', $options);
}
error('登录失效或其他错误,请尝试刷新页面', - 3);
function success($message = '', $data = []) {
echo json_encode([
'code' => 0,
'message' => $message,
'data' => $data
], JSON_UNESCAPED_UNICODE);
exit;
}
function error($message = '', $code = - 1) {
header('Status:500');
echo json_encode([
'code' => $code,
'message' => $message
], JSON_UNESCAPED_UNICODE);
exit;
}

134
index.php
View file

@ -1,21 +1,33 @@
<?php <?php
/* /*
Plugin Name: WP-China-Yes * Plugin Name: WP-China-Yes
Description: 此插件将全面替换WP访问官方服务的链接为高速稳定的中国大陆节点以此加快站点更新版本、安装升级插件主题的速度并彻底解决429报错问题。 * Description: 此插件将全面改善中国大陆站点在访问官方服务时的用户体验,原理是将官方仓库源替换为由社区志愿者维护的国内源。
Author: 孙锡源 * Author: 孙锡源
Version: 1.0.1 * Version: 1.9.9
Author URI:https://www.ibadboy.net/ * Author URI:https://www.ibadboy.net/
*/ * License: GPLv3 or later
* License URI: http://www.gnu.org/licenses/gpl-3.0.html
*/
define('WP_CHINA_YES_PATH', __DIR__); define('WP_CHINA_YES_PATH', __DIR__);
define('WP_CHINA_YES_BASE_FILE', __FILE__); define('WP_CHINA_YES_BASE_FILE', __FILE__);
define('WP_CHINA_YES_VERSION', '1.0.0');
WP_CHINA_YES::init(); WP_CHINA_YES::init();
class WP_CHINA_YES { class WP_CHINA_YES {
public static string $name = 'wp_china_yes';
public static string $option_name = 'wp_china_yes_option';
public static function init() { public static function init() {
if (is_admin()) { if (is_admin()) {
register_activation_hook(WP_CHINA_YES_BASE_FILE, array(
__CLASS__,
'wp_china_yes_activate'
));
register_deactivation_hook(WP_CHINA_YES_BASE_FILE, array(
__CLASS__,
'wp_china_yes_deactivate'
));
add_filter('pre_http_request', array( add_filter('pre_http_request', array(
__CLASS__, __CLASS__,
'pre_http_request' 'pre_http_request'
@ -24,16 +36,41 @@ class WP_CHINA_YES {
__CLASS__, __CLASS__,
'plugin_row_meta' 'plugin_row_meta'
), 10, 2); ), 10, 2);
add_filter('plugin_action_links', array(
__CLASS__,
'action_links'
), 10, 2);
add_action('admin_menu', array(
__CLASS__,
'admin_menu'
));
} }
} }
public static function wp_china_yes_activate() {
$options = array();
$options['community'] = 0;
$options['custom_api_server'] = '';
$options['custom_download_server'] = '';
$options['api_server'] = 'api.w.org.ibadboy.net';
$options['download_server'] = 'd.w.org.ibadboy.net';
add_option('wp_china_yes_options', $options);
}
public static function wp_china_yes_deactivate() {
delete_option('wp_china_yes_options');
}
public static function pre_http_request($preempt, $r, $url) { public static function pre_http_request($preempt, $r, $url) {
if ( ! stristr($url, 'api.wordpress.org') && ! stristr($url, 'downloads.wordpress.org')) { if ( ! stristr($url, 'api.wordpress.org') && ! stristr($url, 'downloads.wordpress.org')) {
return false; return false;
} }
$url = str_replace('api.wordpress.org', 'api.w.org.ibadboy.net', $url); $options = get_option('wp_china_yes_options');
$url = str_replace('downloads.wordpress.org', 'd.w.org.ibadboy.net', $url); $api_server = $options["custom_api_server"] ?: $options["api_server"];
$download_server = $options["custom_download_server"] ?: $options["download_server"];
$url = str_replace('api.wordpress.org', $api_server, $url);
$url = str_replace('downloads.wordpress.org', $download_server, $url);
if (function_exists('wp_kses_bad_protocol')) { if (function_exists('wp_kses_bad_protocol')) {
if ($r['reject_unsafe_urls']) { if ($r['reject_unsafe_urls']) {
@ -54,14 +91,11 @@ class WP_CHINA_YES {
return new WP_Error('http_request_failed', __('A valid URL was not provided.')); return new WP_Error('http_request_failed', __('A valid URL was not provided.'));
} }
// If we are streaming to a file but no filename was given drop it in the WP temp dir
// and pick its name using the basename of the $url
if ($r['stream']) { if ($r['stream']) {
if (empty($r['filename'])) { if (empty($r['filename'])) {
$r['filename'] = get_temp_dir() . basename($url); $r['filename'] = get_temp_dir() . basename($url);
} }
// Force some settings if we are streaming to a file and check for existence and perms of destination directory
$r['blocking'] = true; $r['blocking'] = true;
if ( ! wp_is_writable(dirname($r['filename']))) { if ( ! wp_is_writable(dirname($r['filename']))) {
return new WP_Error('http_request_failed', __('Destination directory for file streaming does not exist or is not writable.')); return new WP_Error('http_request_failed', __('Destination directory for file streaming does not exist or is not writable.'));
@ -72,13 +106,11 @@ class WP_CHINA_YES {
$r['headers'] = array(); $r['headers'] = array();
} }
// WP allows passing in headers as a string, weirdly.
if ( ! is_array($r['headers'])) { if ( ! is_array($r['headers'])) {
$processedHeaders = WP_Http::processHeaders($r['headers']); $processedHeaders = WP_Http::processHeaders($r['headers']);
$r['headers'] = $processedHeaders['headers']; $r['headers'] = $processedHeaders['headers'];
} }
// Setup arguments
$headers = $r['headers']; $headers = $r['headers'];
$data = $r['body']; $data = $r['body'];
$type = $r['method']; $type = $r['method'];
@ -98,17 +130,14 @@ class WP_CHINA_YES {
$options['redirects'] = $r['redirection']; $options['redirects'] = $r['redirection'];
} }
// Use byte limit, if we can
if (isset($r['limit_response_size'])) { if (isset($r['limit_response_size'])) {
$options['max_bytes'] = $r['limit_response_size']; $options['max_bytes'] = $r['limit_response_size'];
} }
// If we've got cookies, use and convert them to Requests_Cookie.
if ( ! empty($r['cookies'])) { if ( ! empty($r['cookies'])) {
$options['cookies'] = WP_Http::normalize_cookies($r['cookies']); $options['cookies'] = WP_Http::normalize_cookies($r['cookies']);
} }
// SSL certificate handling
if ( ! $r['sslverify']) { if ( ! $r['sslverify']) {
$options['verify'] = false; $options['verify'] = false;
$options['verifyname'] = false; $options['verifyname'] = false;
@ -116,24 +145,12 @@ class WP_CHINA_YES {
$options['verify'] = $r['sslcertificates']; $options['verify'] = $r['sslcertificates'];
} }
// All non-GET/HEAD requests should put the arguments in the form body.
if ('HEAD' !== $type && 'GET' !== $type) { if ('HEAD' !== $type && 'GET' !== $type) {
$options['data_format'] = 'body'; $options['data_format'] = 'body';
} }
/**
* Filters whether SSL should be verified for non-local requests.
*
* @param bool $ssl_verify Whether to verify the SSL connection. Default true.
* @param string $url The request URL.
*
* @since 2.8.0
* @since 5.1.0 The `$url` parameter was added.
*
*/
$options['verify'] = apply_filters('https_ssl_verify', $options['verify'], $url); $options['verify'] = apply_filters('https_ssl_verify', $options['verify'], $url);
// Check for proxies.
$proxy = new WP_HTTP_Proxy(); $proxy = new WP_HTTP_Proxy();
if ($proxy->is_enabled() && $proxy->send_through_proxy($url)) { if ($proxy->is_enabled() && $proxy->send_through_proxy($url)) {
$options['proxy'] = new Requests_Proxy_HTTP($proxy->host() . ':' . $proxy->port()); $options['proxy'] = new Requests_Proxy_HTTP($proxy->host() . ':' . $proxy->port());
@ -145,17 +162,14 @@ class WP_CHINA_YES {
} }
} }
// Avoid issues where mbstring.func_overload is enabled
mbstring_binary_safe_encoding(); mbstring_binary_safe_encoding();
try { try {
$requests_response = Requests::request($url, $headers, $data, $type, $options); $requests_response = Requests::request($url, $headers, $data, $type, $options);
// Convert the response into an array
$http_response = new WP_HTTP_Requests_Response($requests_response, $r['filename']); $http_response = new WP_HTTP_Requests_Response($requests_response, $r['filename']);
$response = $http_response->to_array(); $response = $http_response->to_array();
// Add the original object to the array.
$response['http_response'] = $http_response; $response['http_response'] = $http_response;
} catch (Requests_Exception $e) { } catch (Requests_Exception $e) {
$response = new WP_Error('http_request_failed', $e->getMessage()); $response = new WP_Error('http_request_failed', $e->getMessage());
@ -163,18 +177,6 @@ class WP_CHINA_YES {
reset_mbstring_encoding(); reset_mbstring_encoding();
/**
* Fires after an HTTP API response is received and before the response is returned.
*
* @param array|WP_Error $response HTTP response or WP_Error object.
* @param string $context Context under which the hook is fired.
* @param string $class HTTP transport used.
* @param array $r HTTP request arguments.
* @param string $url The request URL.
*
* @since 2.8.0
*
*/
do_action('http_api_debug', $response, 'response', 'Requests', $r, $url); do_action('http_api_debug', $response, 'response', 'Requests', $r, $url);
if (is_wp_error($response)) { if (is_wp_error($response)) {
return $response; return $response;
@ -193,25 +195,47 @@ class WP_CHINA_YES {
); );
} }
/**
* Filters the HTTP API response immediately before the response is returned.
*
* @param array $response HTTP response.
* @param array $r HTTP request arguments.
* @param string $url The request URL.
*
* @since 2.9.0
*
*/
return apply_filters('http_response', $response, $r, $url); return apply_filters('http_response', $response, $r, $url);
} }
public static function plugin_row_meta($links, $file) { public static function plugin_row_meta($links, $file) {
$base = plugin_basename(WP_CHINA_YES_BASE_FILE); $base = plugin_basename(WP_CHINA_YES_BASE_FILE);
if ($file == $base) { if ($file == $base) {
$links[] = '<a href="https://github.com/sunxiyuan/wp-china-yes">插件发布页</a>'; $links[] = '<a target="_blank" href="https://www.ibadboy.net/archives/3204.html">发布地址</a>';
$links[] = '<a target="_blank" href="https://github.com/sunxiyuan/wp-china-yes">GitHub</a>';
} }
return $links; return $links;
} }
public static function action_links($links, $file) {
if ($file != plugin_basename(WP_CHINA_YES_BASE_FILE)) {
return $links;
}
$settings_link = '<a href="' . menu_page_url(self::$name, false) . '">设置</a>';
array_unshift($links, $settings_link);
return $links;
}
public static function admin_menu() {
add_options_page(
'WP-China-Yes',
'WP-China-Yes',
'manage_options',
self::$name,
array(__CLASS__, 'settings')
);
}
public static function settings() {
echo <<<EOT
<div style="height: 20px"></div>
<iframe src="/wp-content/plugins/wp-china-yes/settings.html"
frameborder="0" height="850" width="800px;" scrolling="No" leftmargin="0" topmargin="0">
</iframe>
EOT;
}
} }

View file

@ -2,20 +2,29 @@
## 介绍 ## 介绍
因为WordPress的服务器都在国外所以中国大陆的用户在访问由WordPress官方提供的服务时总是很缓慢。 因为WordPress官方的服务器都在国外所以中国大陆的用户在访问由WordPress官方提供的服务插件、主题商城WP程序版本更新等时总是很缓慢。
近期又因为被攻击的原因WordPress的CDN提供商屏蔽了中国大陆的流量导致大陆用户访问插件主题商城等服务时报429错误。 近期又因为被攻击的原因WordPress的CDN提供商屏蔽了中国大陆的流量导致大陆用户访问插件主题商城等服务时报429错误。
为解决上述问题我在大陆境内架设了缓存加速节点用以加快WordPress官方服务在中国大陆的访问速度并规避429报错问题。 为解决上述问题,我在大陆境内架设了基于反向代理的缓存加速节点用以加快WordPress官方服务在中国大陆的访问速度并规避429报错问题。
为使更多的使用WordPress的同学能够用上大陆加速节点我开发了WP-China-Yes插件以求帮助大家方便简洁的替换服务链接。 此加速节点是直接为你的站点与WordPress总部服务器的一切通信做加速加速范围包括但不限于插件、主题商城的资源下载、作品图片、作者头像、主题预览等……
为使更多的使用WordPress的同学能够用上大陆加速节点我开发了WP-China-Yes插件以求帮助大家方便简洁的替换官方服务链接为大陆节点。
这个是一个公益项目,我始终都不会以任何借口对插件、加速节点的使用权等进行收费。
## 使用方法 ## 使用方法
Master上的是开发中的版本可能存在BUG。推荐安装最新稳定版[点击下载](https://github.com/sunxiyuan/wp-china-yes/releases/download/v1.0.1/wp-china-yes.zip)
下载并安装插件后直接启用即可该插件会自动接管所有WP访问境外服务器的流量。 下载并安装插件后直接启用即可该插件会自动接管所有WP访问境外服务器的流量。
## 广告 ## 开发计划
我在开发一个WordPress数据库实时增量备份的插件该插件可以做到回溯数据到任意时间点。 ### v2.0.0
- 社区源列表 已完成,等待测试
插件最终会以开源的形式放出对此感兴趣的朋友请加我QQ1642491905提供你的宝贵建议并担任测试人员 ^_^ - 自定义源支持 已完成,等待测试
### v1.0.0
- 基本功能 已完成

View file

@ -5,15 +5,17 @@ Tags: China Super, 429, WP China Yes, wp-china-yes, WP-China-Yes
Requires at least: 4.5 Requires at least: 4.5
Tested up to: 5.4.0 Tested up to: 5.4.0
Requires PHP: 5.2 Requires PHP: 5.2
Stable tag: 1.0.1 Stable tag: 2.0.0
License: GPLv3 or later License: GPLv3 or later
License URI: http://www.gnu.org/licenses/gpl-3.0.html License URI: http://www.gnu.org/licenses/gpl-3.0.html
WP-China-Yes将接管WP站点访问官方服务时的一切流量到大陆加速节点包括但不限于插件主题的安装、商城图片的展示、作者的头像、主题的预览等……从而全面加快WP站点后台的访问速度并解决429报错问题 W此插件将全面改善中国大陆站点在访问官方服务时的用户体验,原理是将官方仓库源替换为由社区志愿者维护的国内源。
== Description == == Description ==
WP-China-Yes将接管WP站点访问官方服务时的一切流量到大陆加速节点包括但不限于插件主题的安装、商城图片的展示、作者的头像、主题的预览等……从而全面加快WP站点后台的访问速度并解决429报错问题 因为WordPress官方的服务器都在国外所以中国大陆的用户在访问由WordPress官方提供的服务插件、主题商城WP程序版本更新等时总是很缓慢。
近期又因为被攻击的原因WordPress的CDN提供商屏蔽了中国大陆的流量导致大陆用户访问插件主题商城等服务时报429错误。
为解决上述问题我开发了WP-China-Yes插件该插件可以将WP站点访问官方服务的一切流量迁移到由社区志愿者维护的大陆源上从而全面优化用户体验。
== Frequently Asked Questions == == Frequently Asked Questions ==
@ -23,5 +25,9 @@ WP-China-Yes将接管WP站点访问官方服务时的一切流量到大陆加速
== Changelog == == Changelog ==
= 2.0.0 =
* 社区源列表 完成
* 自定义源支持 完成
= 1.0.1 = = 1.0.1 =
* 基本功能完成 * 基本功能 完成

223
settings.html Normal file
View file

@ -0,0 +1,223 @@
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>WP-China-Yes设置页</title>
<link rel="stylesheet"
href="https://static.ibadboy.net/element/static/css/index.css">
</head>
<body id="body" style="display: none;">
<div id="app">
<el-container>
<el-header style="height: 100px;">
<h2>WP-China-Yes</h2>
<span>这是一个颠覆性的插件,她将全面改善中国大陆站点在访问官方服务时的用户体验</span><br/>
<span>原理是将官方仓库源替换为由社区志愿者维护的国内源,以此达到加速的目的</span>
</el-header>
<el-main>
<el-divider></el-divider>
<el-tabs tab-position="right" style="height: 520px;">
<el-tab-pane label="插件设置">
<el-container>
<el-main class="no_top_main_box">
<el-form ref="mirrors_form" :model="mirrors_form"
label-width="100px" size="small"
style="width: 342px;">
<el-card class="box-card" shadow="hover">
<div slot="header">
<span>使用社区源</span>
</div>
<el-form-item label="选择社区源">
<el-select v-model="mirrors_form.community"
@change="changeServer"
placeholder="请选择社区源">
<el-option v-for="(item,index) in external_api.server"
:label="item.name"
:value="item.id"></el-option>
</el-select>
</el-form-item>
<el-alert
:title="server_desc"
type="info"
:closable="false"
style="width: 422px; margin-left: 20px;"
show-icon>
</el-alert>
</el-card>
<el-card class="box-card" shadow="hover">
<div slot="header">
<span>自定义源</span>
<span style="font-size: 12px; margin-left: 10px;">若配置自定义源则会覆盖社区源</span>
<el-link href="https://www.ibadboy.net/archives/3349.html"
style="float: right;"
type="primary"
target="_blank"
:underline="false">搭建方法
</el-link>
</div>
<el-form-item label="API服务器" style="width: 442px;">
<el-input clearable
v-model="mirrors_form.custom_api_server">
<template slot="prepend">https://</template>
</el-input>
</el-form-item>
<el-form-item label="下载服务器" style="width: 442px;">
<el-input clearable
v-model="mirrors_form.custom_download_server">
<template slot="prepend">https://</template>
</el-input>
</el-form-item>
</el-card>
<el-card class="box-card"
style="height: 60px; text-align:center;"
shadow="never">
<el-button style="margin-top: -7px;"
type="primary"
@click="submitMirrorsForm" size="medium">保存配置
</el-button>
</el-card>
</el-form>
</el-main>
</el-container>
</el-tab-pane>
<!--
<el-tab-pane label="贡献者名单">
</el-tab-pane>
<el-tab-pane label="捐助者名单">
</el-tab-pane>
-->
<el-tab-pane label="广告列表">
</el-tab-pane>
</el-tabs>
</el-main>
<el-divider></el-divider>
<el-footer>
<span class="desc">这是一个开源项目,她需要每个人的支持和贡献才能健康长久的发展。</span><br/>
<span class="desc">项目地址:<a target="_blank"
href="https://github.com/sunxiyuan/wp-china-yes">GitHub</a></span>
</el-footer>
</el-container>
</div>
</body>
<script src="https://static.ibadboy.net/element/static/js/vue.js"></script>
<script src="https://static.ibadboy.net/element/static/js/index.js"></script>
<script src="https://static.ibadboy.net/element/static/js/axios.min.js"></script>
<script>
new Vue({
el: '#app',
data() {
return {
external_api: {},
server_desc: '',
mirrors_form: {
community: '0',
custom_api_server: '',
custom_download_server: '',
api_server: '',
download_server: '',
}
}
},
methods: {
changeServer() {
let server = this.external_api.server[this.mirrors_form.community];
//console.log(this.external_api.server);
this.server_desc = server.desc;
this.mirrors_form.api_server = server.api_server;
this.mirrors_form.download_server = server.download_server;
},
getConfig() {
let vm = this;
axios.get('/wp-content/plugins/wp-china-yes/api.php?get_config')
.then(function (response) {
vm.mirrors_form = response.data.data;
})
.catch(function (error) {
vm.$message({
message: error.response.data.message,
type: 'error'
});
});
axios.get('https://wp-china-yes.ibadboy.net')
.then(function (response) {
vm.external_api = response.data;
vm.changeServer();
})
.catch(function (error) {
vm.$message({
message: error,
type: 'error'
});
});
},
submitMirrorsForm() {
let vm = this;
this.$confirm('这将覆盖旧有配置, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
const loading = this.$loading({
lock: true,
text: 'Loading',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
let data = new FormData();
data.append('community', vm.mirrors_form.community);
data.append('custom_api_server', vm.mirrors_form.custom_api_server);
data.append('custom_download_server', vm.mirrors_form.custom_download_server);
data.append('api_server', vm.mirrors_form.api_server);
data.append('download_server', vm.mirrors_form.download_server);
axios.post('/wp-content/plugins/wp-china-yes/api.php', data)
.then(function (response) {
vm.$message({
message: '保存成功',
type: 'success'
});
loading.close();
})
.catch(function (error) {
vm.$message({
message: error.response.data.message,
type: 'error'
});
loading.close();
});
}).catch(() => {
this.$message({
type: 'info',
message: '已取消保存'
});
});
}
},
created: function () {
document.getElementById("body").style.display = "inline";
this.getConfig();
}
})
</script>
<style>
.desc {
font-size: 14px;
font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
}
.box-card {
margin-top: 20px;
width: 500px;
}
.no_top_main_box {
padding-top: 0;
}
</style>
</html>