| 1 |
<?php |
| 2 |
/* |
| 3 |
Name: Admin |
| 4 |
Description: 后台 |
| 5 |
Version: 2.0 |
| 6 |
Admin: true |
| 7 |
*/ |
| 8 |
class WPJAM_Basic_Admin{ |
| 9 |
public static function on_admin_init(){ |
| 10 |
foreach([ |
| 11 |
'wpjam-user' => ['menu_title'=>'用户设置', 'order'=>16], |
| 12 |
'wpjam-page' => ['menu_title'=>'页面设置', 'order'=>15], |
| 13 |
'wpjam-links' => ['menu_title'=>'链接设置', 'order'=>14], |
| 14 |
'wpjam-seo' => ['menu_title'=>'SEO 设置', 'order'=>12], |
| 15 |
'wpjam-about' => ['menu_title'=>'� |
| 16 |
�于WPJAM', 'order'=>1, 'function'=>[self::class, 'about_page']], |
| 17 |
'wpjam-icons' => ['menu_title'=>'图标列表', 'order'=>9, 'tabs'=>['dashicons'=>['title'=>'Dashicons', 'function'=>[self::class, 'dashicons_page']]]], |
| 18 |
] as $slug => $args){ |
| 19 |
if($args['order'] < 10 || wpjam_filter(wpjam_admin('tabs[]'), fn($v)=> wpjam_get($v, 'plugin_page') == $slug)){ |
| 20 |
wpjam_add_menu_page($slug, $args+['parent'=>'wpjam-basic', 'function'=>'tab', 'network'=>false]); |
| 21 |
} |
| 22 |
} |
| 23 |
|
| 24 |
wpjam_add_admin_load(['type'=>'builtin_page', 'model'=> self::class]); |
| 25 |
|
| 26 |
add_action('admin_menu', fn()=> $GLOBALS['menu'] += ['58.88'=> ['', 'read', 'separator'.'58.88', '', 'wp-menu-separator']]); |
| 27 |
|
| 28 |
if(get_transient('wpjam_basic_verify')){ |
| 29 |
wpjam_admin('pages[wpjam-basic][subs][wpjam-about]', null); |
| 30 |
}elseif(WPJAM_Verify::verify()){ |
| 31 |
if(isset($_GET['unbind_wpjam_user'])){ |
| 32 |
delete_user_meta(get_current_user_id(), 'wpjam_weixin_user'); |
| 33 |
|
| 34 |
wp_redirect(admin_url('admin.php?page=wpjam-verify')); |
| 35 |
} |
| 36 |
}else{ |
| 37 |
wpjam_admin('pages[wpjam-basic][subs]', ['wpjam-verify'=> [ |
| 38 |
'menu_title' => '扩展管理', |
| 39 |
'page_title' => '验证 WPJAM', |
| 40 |
'function' => 'form', |
| 41 |
'model' => 'WPJAM_Verify' |
| 42 |
]]); |
| 43 |
} |
| 44 |
} |
| 45 |
|
| 46 |
public static function dashicons_page(){ |
| 47 |
$file = fopen(ABSPATH.'/'.WPINC.'/css/dashicons.css','r'); |
| 48 |
$html = []; |
| 49 |
|
| 50 |
while(!feof($file)){ |
| 51 |
$line = fgets($file); |
| 52 |
$icon = $line && preg_match_all('/.dashicons-(.*?):before/i', $line, $matches) ? $matches[1][0] : ''; |
| 53 |
$html[] = $icon && $icon != 'before' ? wpjam_tag('span', ['dashicons-before', 'dashicons-'.$icon])->after('<br />'.$icon)->wrap('p', ['data-dashicon'=>'dashicons-'.$icon]) : ''; |
| 54 |
} |
| 55 |
|
| 56 |
fclose($file); |
| 57 |
|
| 58 |
echo '<div class="wpjam-icons">'.implode($html).'</div>'.'<div class="clear"></div>'; |
| 59 |
?> |
| 60 |
<style type="text/css"> |
| 61 |
div.wpjam-icons{max-width: 800px; display: flex; flex-wrap: wrap;} |
| 62 |
div.wpjam-icons p{ margin:0px 10px 10px 0; padding: 10px; width:70px; text-align: center; cursor: pointer;} |
| 63 |
div.wpjam-icons .dashicons-before:before{font-size:32px; width: 32px; height: 32px;} |
| 64 |
</style> |
| 65 |
<script type="text/javascript"> |
| 66 |
jQuery(function($){ |
| 67 |
$('body').on('click', 'div.wpjam-icons p', function(){ |
| 68 |
let dashicon = $(this).data('dashicon'); |
| 69 |
|
| 70 |
wpjam.dialog('<div style="display:flex;"><p><span style="font-size:100px; width: 100px; height: 100px;" class="dashicons '+dashicon+'"></span></p><p style="margin-left:20px; font-size:20px;">'+dashicon+'<br /><br />HTML:<br /><code><span class="dashicons '+dashicon+'"></span></code></p></dov>', dashicon); |
| 71 |
}); |
| 72 |
}); |
| 73 |
</script> |
| 74 |
<?php |
| 75 |
} |
| 76 |
|
| 77 |
public static function about_page(){ |
| 78 |
$jam_plugins = wpjam_transient('about_jam_plugins', fn()=> wpjam_remote_request(self::api_url('about'), ['field'=>'body.template.table.content'])); |
| 79 |
|
| 80 |
?> |
| 81 |
<div style="max-width: 900px;"> |
| 82 |
<?php if(is_array($jam_plugins)){ ?><table id="jam_plugins" class="widefat striped"> |
| 83 |
<tbody> |
| 84 |
<tr> |
| 85 |
<th colspan="2"> |
| 86 |
<h2>WPJAM 插件</h2> |
| 87 |
<p>加� |
| 88 |
�<a href="https://97866.com/s/zsxq/">「WordPress果� |
| 89 |
�」知识星球</a>即可下载:</p> |
| 90 |
</th> |
| 91 |
</tr> |
| 92 |
<?php foreach($jam_plugins as $jam_plugin){ ?> |
| 93 |
<tr> |
| 94 |
<th style="width: 100px;"><p><strong><a href="<?php echo $jam_plugin['i2']; ?>"><?php echo $jam_plugin['i1']; ?></a></strong></p></th> |
| 95 |
<td><?php echo wpautop($jam_plugin['i3']); ?></td> |
| 96 |
</tr> |
| 97 |
<?php }?> |
| 98 |
</tbody> |
| 99 |
</table><?php } ?> |
| 100 |
|
| 101 |
<div class="card"> |
| 102 |
<h2>WPJAM Basic</h2> |
| 103 |
|
| 104 |
<p><strong><a href="https://blog.wpjam.com/project/wpjam-basic/">WPJAM Basic</a></strong> 是 <strong><a href="https://blog.wpjam.com/">我爱水� |
| 105 |
�鱼</a></strong> 的 Denis 开发的 WordPress 插件。</p> |
| 106 |
|
| 107 |
<p>WPJAM Basic 除了能够优化你的 WordPress ,也是 「WordPress 果� |
| 108 |
�」团队进行 WordPress 二次开发的基础。</p> |
| 109 |
<p>为了方便开发,WPJAM Basic 使用了最新的 PHP 7.2 语法,所以要使用该插件,需要你的服务器的 PHP 版本是 7.2 或� |
| 110 |
更高。</p> |
| 111 |
<p>我们开发所有插件都需要<strong>首� |
| 112 |
�安� |
| 113 |
</strong> WPJAM Basic,� |
| 114 |
�他功能组件将以扩展的模式整合到 WPJAM Basic 插件一并发布。</p> |
| 115 |
</div> |
| 116 |
|
| 117 |
<div class="card"> |
| 118 |
<h2>WPJAM 优化</h2> |
| 119 |
<p>网站优化首� |
| 120 |
�依托于强劲的服务器支撑,这里强烈建议使用<a href="https://wpjam.com/go/aliyun/">阿里云</a>或<a href="https://wpjam.com/go/qcloud/">� |
| 121 |
�讯云</a>。</p> |
| 122 |
<p>更详细的 WordPress 优化请参考:<a href="https://blog.wpjam.com/article/wordpress-performance/">WordPress 性能优化:为什么我的博客比你的快</a>。</p> |
| 123 |
<p>我们也提供专业的 <a href="https://blog.wpjam.com/article/wordpress-optimization/">WordPress 性能优化服务</a>。</p> |
| 124 |
</div> |
| 125 |
</div> |
| 126 |
<style type="text/css"> |
| 127 |
.card {max-width: 320px; float: left; margin-top:20px;} |
| 128 |
.card a{text-decoration: none;} |
| 129 |
table#jam_plugins{margin-top:20px; width: 520px; float: left; margin-right: 20px;} |
| 130 |
table#jam_plugins th{padding-left: 2em; } |
| 131 |
table#jam_plugins td{padding-right: 2em;} |
| 132 |
table#jam_plugins th p, table#jam_plugins td p{margin: 6px 0;} |
| 133 |
</style> |
| 134 |
<?php |
| 135 |
} |
| 136 |
|
| 137 |
private static function api_url($type){ |
| 138 |
return 'https://jam.wpweixin.com/api/template/get.json?'.($type == 'about' ? 'id=5644' : 'name=wpjam-'.$type.'-versions'); |
| 139 |
} |
| 140 |
|
| 141 |
public static function builtin_page_load($screen){ |
| 142 |
if(in_array($screen->base, ['dashboard', 'dashboard-network', 'dashboard-user'])){ |
| 143 |
is_multisite() && !is_user_member_of_blog() && remove_meta_box('dashboard_quick_press', get_current_screen(), 'side'); |
| 144 |
|
| 145 |
$args = ['post_type'=>get_post_types(['show_ui'=>true, 'public'=>true, '_builtin'=>false])+['post']]; |
| 146 |
|
| 147 |
wpjam_hooks('dashboard_recent_posts_query_args, dashboard_recent_drafts_query_args', '+', $args+['cache_results'=>true]); |
| 148 |
|
| 149 |
add_action('pre_get_comments', fn($query)=> $query->query_vars = array_merge($query->query_vars, $args+['type'=>'comment'])); |
| 150 |
|
| 151 |
wpjam_dashboard('load', ['name'=>'dashboard', 'widgets'=>['wpjam_update'=>[ |
| 152 |
'title' => 'WordPress资讯及技巧', |
| 153 |
'context' => 'side', |
| 154 |
'callback' => function(){ |
| 155 |
$posts = wpjam_transient('jam_dashboard_posts', fn()=> wpjam_remote_request('https://jam.wpweixin.com/api/post/list.json', ['timeout'=>1, 'field'=>'body.posts'])); |
| 156 |
|
| 157 |
echo is_array($posts) ? '<div class="rss-widget">'.implode(array_map(fn($p)=> '<a class="jam-post" target="_blank" href="http://blog.wpjam.com'.$p['post_url'].'"><p>'.'<img src="'.str_replace('imageView2/1/w/200/h/200/', 'imageView2/1/w/100/h/100/', $p['thumbnail']).'" /><span>'.$p['title'].'</span></p></a>', array_slice($posts, 0, 5))).'</div>' : ''; |
| 158 |
} |
| 159 |
]]]); |
| 160 |
|
| 161 |
wpjam_style([ |
| 162 |
'#dashboard_wpjam .inside{margin:0; padding:0;}', |
| 163 |
'a.jam-post {border-bottom:1px solid #eee; margin: 0 !important; padding:6px 0; display: block; text-decoration: none; }', |
| 164 |
'a.jam-post:last-child{border-bottom: 0;}', |
| 165 |
'a.jam-post p{display: table-row; }', |
| 166 |
'a.jam-post img{display: table-cell; width:40px; height: 40px; margin:4px 12px; }', |
| 167 |
'a.jam-post span{display: table-cell; height: 40px; vertical-align: middle;}' |
| 168 |
]); |
| 169 |
}elseif($base = array_find(['plugins', 'themes', 'update-core'], fn($base)=> str_starts_with($screen->base, $base))){ |
| 170 |
foreach(['plugin', 'theme'] as $type){ |
| 171 |
wpjam_updater($type, 'blog.wpjam.com', self::api_url($type)); |
| 172 |
|
| 173 |
// wpjam_print_r(get_site_transient('update_'.$type.'s')); |
| 174 |
// delete_site_transient('update_'.$type.'s'); |
| 175 |
} |
| 176 |
|
| 177 |
add_filter('pre_set_site_transient_update_plugins', function($updates){ |
| 178 |
$file = 'wpjam-basic/wpjam-basic.php'; |
| 179 |
|
| 180 |
if($key = array_find(['response', 'no_update'], fn($k)=> isset($updates->$k[$file]))){ |
| 181 |
$plugin = get_plugin_data(WP_PLUGIN_DIR.'/'.$file); |
| 182 |
$update = apply_filters('update_plugins_blog.wpjam.com', false, $plugin, $file, []); |
| 183 |
|
| 184 |
if($update && is_array($update) && version_compare($update['new_version'], $plugin['Version'], '>')){ |
| 185 |
$updates->response[$file] = (object)(array_merge((array)$updates->$key[$file], $update)); |
| 186 |
|
| 187 |
unset($updates->no_update[$file]); |
| 188 |
} |
| 189 |
} |
| 190 |
|
| 191 |
return $updates; |
| 192 |
}); |
| 193 |
} |
| 194 |
} |
| 195 |
} |
| 196 |
|
| 197 |
class WPJAM_Verify{ |
| 198 |
public static function verify(){ |
| 199 |
$verify_user = get_user_meta(get_current_user_id(), 'wpjam_weixin_user', true); |
| 200 |
|
| 201 |
if(empty($verify_user)){ |
| 202 |
return false; |
| 203 |
} |
| 204 |
|
| 205 |
if(time() - $verify_user['last_update'] < DAY_IN_SECONDS){ |
| 206 |
return true; |
| 207 |
} |
| 208 |
|
| 209 |
$openid = $verify_user['openid']; |
| 210 |
$hash = $verify_user['hash'] ?? ''; |
| 211 |
$user_id = get_current_user_id(); |
| 212 |
|
| 213 |
if(wpjam_lock('fetching_wpjam_weixin_user_'.$openid, 10)){ |
| 214 |
return false; |
| 215 |
} |
| 216 |
|
| 217 |
$response = self::request(['openid'=>$openid, 'hash'=>$hash]); |
| 218 |
|
| 219 |
if(is_wp_error($response) && $response->get_error_code() != 'invalid_openid'){ |
| 220 |
$failed_times = (int)get_user_meta($user_id, 'wpjam_weixin_user_failed_times'); |
| 221 |
$failed_times ++; |
| 222 |
|
| 223 |
if($failed_times >= 3){ // 重复三次 |
| 224 |
delete_user_meta($user_id, 'wpjam_weixin_user_failed_times'); |
| 225 |
delete_user_meta($user_id, 'wpjam_weixin_user'); |
| 226 |
}else{ |
| 227 |
update_user_meta($user_id, 'wpjam_weixin_user_failed_times', $failed_times); |
| 228 |
} |
| 229 |
|
| 230 |
return false; |
| 231 |
} |
| 232 |
|
| 233 |
delete_user_meta($user_id, 'wpjam_weixin_user_failed_times'); |
| 234 |
|
| 235 |
if(empty($response) || !is_array($response) || !$response['subscribe']){ |
| 236 |
delete_user_meta($user_id, 'wpjam_weixin_user'); |
| 237 |
|
| 238 |
return false; |
| 239 |
} |
| 240 |
|
| 241 |
update_user_meta($user_id, 'wpjam_weixin_user', array_merge($response, ['last_update'=>time()])); |
| 242 |
|
| 243 |
return true; |
| 244 |
} |
| 245 |
|
| 246 |
public static function request($data, $throw=false){ |
| 247 |
return wpjam_remote_request('https://wpjam.wpweixin.com/api/weixin/verify.json', ['method'=>'POST', 'body'=>$data, 'throw'=>$throw]); |
| 248 |
} |
| 249 |
|
| 250 |
public static function get_form(){ |
| 251 |
wpjam_style('.form-table th{width: 100px;}'); |
| 252 |
|
| 253 |
$qrcode = wpjam_tag('img', ['src'=>'https://open.weixin.qq.com/qr/code?username=wpjamcom', 'style'=>'max-width:250px;'])->wrap('p')->before('p', [], '使用微信扫描下面的二维码:'); |
| 254 |
|
| 255 |
return [ |
| 256 |
'submit_text' => '验证', |
| 257 |
'response' => 'redirect', |
| 258 |
'validate' => true, |
| 259 |
'callback' => function($data){ |
| 260 |
update_user_meta(get_current_user_id(), 'wpjam_weixin_user', array_merge(self::request($data, true), ['last_update'=>time(), 'subscribe'=>1])); |
| 261 |
|
| 262 |
return ['url'=>admin_url('page=wpjam-extends')]; |
| 263 |
}, |
| 264 |
'fields' => [ |
| 265 |
'qr_view' => ['title'=>'1. 二维码', 'type'=>'view', 'value'=>$qrcode], |
| 266 |
'keyword' => ['title'=>'2. � |
| 267 |
�键字', 'type'=>'view', 'value'=>'回复� |
| 268 |
�键字「<strong>验证码</strong>」。'], |
| 269 |
'code' => ['title'=>'3. 验证码', 'type'=>'number', 'required', 'before'=>'将获取验证码输� |
| 270 |
�提交即可'], |
| 271 |
'notes' => ['title'=>'4. 注意事项', 'type'=>'view', 'value'=>'<p>验证码5分钟� |
| 272 |
有效!</p><p>如果验证不通过,请使用 Chrome 浏览器验证,并在验证之前� |
| 273 |
理浏览器缓存。<br />如多次测试无法通过,可以尝试重新� |
| 274 |
�注� |
| 275 |
�众号测试!</p>'], |
| 276 |
] |
| 277 |
]; |
| 278 |
} |
| 279 |
} |
| 280 |
|
| 281 |
add_action('wpjam_admin_init', ['WPJAM_Basic_Admin', 'on_admin_init'], 99); |