PluginProbe
WPJAM Basic / trunk
WPJAM Basic vtrunk
wpjam-basic / components / wpjam-admin.php

wpjam-admin.php in WPJAM Basic trunk, at components/wpjam-admin.php

281 lines 11.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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>&lt;span class="dashicons '+dashicon+'"&gt;&lt;/span&gt;</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);