PluginProbe
WPJAM Basic / trunk
WPJAM Basic vtrunk
wpjam-basic / public / wpjam-route.php

wpjam-route.php in WPJAM Basic trunk, at public/wpjam-route.php

837 lines 23.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 function wpjam($field='', ...$args){
3 return (WPJAM_API::get_instance())($field, ...$args);
4 }
5
6 function wpjam_var($name, ...$args){
7 $names = str_contains($name, ':') ? explode(':', $name, 2) : ['vars', $name];
8 $value = wpjam(...$names);
9
10 if($args && ($value === null || !is_closure($args[0]))){
11 $value = maybe_closure($args[0], ...array_reverse($names));
12
13 wpjam(...[...$names, wpjam_if_error($value, null)]);
14 }
15
16 return $value;
17 }
18
19 function wpjam_default(...$args){
20 return wpjam('defaults', ...$args);
21 }
22
23 // $name, $data
24 // $data
25 // $name, $cb
26 // $cb
27 function wpjam_config(...$args){
28 if($args && (count($args) > 1 || is_array($args[0]) || is_callable($args[0]))){
29 $group = (count($args) >= 3 ? array_shift($args) : '') ?: 'default';
30 $args = wpjam_filter($args, fn($v)=> isset($v));
31
32 return $args ? wpjam('config', $group.'['.(count($args) > 1 ? array_shift($args) : '').']', ...$args) : null;
33 }
34
35 return wpjam_reduce(wpjam('config', ($args[0] ?? '') ?: 'default') ?: [], function($c, $v, $k){
36 $v = maybe_callback($v);
37 $v = is_numeric($k) ? (is_array($v) ? $v : []) : [$k=>$v];
38
39 return array_merge($c, $v);
40 }, []);
41 }
42
43 // Parameter
44 function wpjam_params($type, $fields=[]){
45 $object = WPJAM_Param::get_instance();
46
47 return $object($type, wp_parse_args($fields));
48 }
49
50 function wpjam_param($name, $args=[]){
51 if(is_array($name)){
52 return $name ? wpjam_map(wp_is_numeric_array($name) ? array_fill_keys($name, $args) : $name, 'wpjam_param', 'kv') : [];
53 }
54
55 $object = WPJAM_Param::get_instance();
56 $type = is_array($args) ? wpjam_pull($args, 'method') : $args;
57
58 return $object($type, $name, is_array($args) ? $args : []);
59 }
60
61 // Request
62 function wpjam_remote_request($url, $args=[], $err=[]){
63 return WPJAM_Http::request($url, $args+['field'=>'body'], $err);
64 }
65
66 function wpjam_translate($text, ...$args){
67 if(is_array($text)){
68 [$trans, $text] = $text;
69
70 return (array_pop($args) !== 'default' && $trans === $text) ? wpjam_translate($text, ...$args) : $trans;
71 }
72
73 $trans = wpjam_call('translate'.($args && $args[0] ? '_with_gettext_context' : ''), $text, ...$args);
74
75 if($trans === $text && substr_count($text, ' ') <= 1 && ($low = strtolower($text)) !== $text){
76 if(($result = wpjam_translate($low, ...$args)) !== $low){
77 $trans = $result;
78 }
79 }
80
81 return $trans;
82 }
83
84 // AJAX
85 function wpjam_ajax($name, $args=[]){
86 if(empty($args['callback'])){
87 $action = wpjam_call_method(WPJAM_AJAX::get($name), 'nonce_action', $args);
88
89 return wpjam_attr(['action'=>$name, 'data'=>$args]+($action ? ['nonce'=>wp_create_nonce($action)] : []), 'data');
90 }elseif(empty($args['admin']) || wp_doing_ajax()){
91 return WPJAM_AJAX::register($name, $args);
92 }
93 }
94
95 // User Agent
96 function wpjam_ua($key='', ...$args){
97 $name = 'user_agent';
98 $ua = wpjam($name) ?: wpjam($name, wpjam_parse_user_agent());
99
100 return $key ? ($args ? wpjam($name, [$key=>$args[0]]+$ua) : $ua[$key]) : $ua;
101 }
102
103 function wpjam_get_device(){
104 return wpjam_ua('device');
105 }
106
107 function wpjam_get_os(){
108 return wpjam_ua('os');
109 }
110
111 function wpjam_get_app(){
112 return wpjam_ua('app');
113 }
114
115 function wpjam_get_browser(){
116 return wpjam_ua('browser');
117 }
118
119 function wpjam_get_version($key){
120 return wpjam_ua($key.'_version');
121 }
122
123 if(!function_exists('is_iphone')){
124 function is_iphone(){
125 return wpjam_ua('device') == 'iPhone';
126 }
127 }
128
129 if(!function_exists('is_ipad')){
130 function is_ipad(){
131 return wpjam_ua('device') == 'iPad';
132 }
133 }
134
135 if(!function_exists('is_ios')){
136 function is_ios(){
137 return wpjam_ua('os') == 'iOS';
138 }
139 }
140
141 if(!function_exists('is_macintosh')){
142 function is_macintosh(){
143 return wpjam_ua('os') == 'Macintosh';
144 }
145 }
146
147 if(!function_exists('is_android')){
148 function is_android(){
149 return wpjam_ua('os') == 'Android';
150 }
151 }
152
153 if(!function_exists('is_weixin')){
154 function is_weixin(){
155 return isset($_GET['weixin_appid']) || wpjam_ua('app') == 'weixin';
156 }
157 }
158
159 if(!function_exists('is_weapp')){
160 function is_weapp(){
161 return isset($_GET['appid']) || wpjam_ua('app') == 'weapp';
162 }
163 }
164
165 if(!function_exists('is_bytedance')){
166 function is_bytedance(){
167 return isset($_GET['bytedance_appid']) || wpjam_ua('app') == 'bytedance';
168 }
169 }
170
171 // Add
172 function wpjam_add($key, $args){
173 if($args = is_string($args) ? wpjam_call_method($args.'::get_'.$key) : $args){
174 return wpjam_call('wpjam_add_'.$key, $args);
175 }
176 }
177
178 // Hook
179 function wpjam_hooks($name, ...$args){
180 if(is_string($name) && str_ends_with($name, '::add_hooks')){
181 $name = wpjam_call_method($name);
182 }
183
184 if(is_array($name)){
185 return wpjam_map(array_filter($name), fn($n)=> wpjam_hooks(...(is_array($n) ? $n : [$n, ...$args])));
186 }
187
188 return WPJAM_Hook::batch(...($name === '-' ? ['remove', ...$args] : ['add', $name, ...$args]));
189 }
190
191 function wpjam_hook($name, ...$args){
192 return is_array($name) ? new WPJAM_Hook($name) : ($name === '-' ? WPJAM_Hook::remove(...$args) : WPJAM_Hook::add($name, ...$args));
193 }
194
195 function wpjam_once($name, ...$args){
196 return wpjam_hook('once', ...wpjam_add_at($args, $name == 'maybe' ? 1 : 0, $name));
197 }
198
199 function wpjam_echo($value, ...$args){
200 if($args && is_string($args[0])){
201 return wpjam_hook(array_shift($args), fn()=> wpjam_echo($value), ...$args);
202 }elseif($args && $args[0] === false){
203 return $value;
204 }else{
205 echo $value;
206 }
207 }
208
209 function wpjam_load($hook, $cb, ...$args){
210 if($cb && is_callable($cb)){
211 if($hook = array_filter((array)$hook, fn($h)=> !did_action($h))){
212 add_action(array_shift($hook), $hook ? fn()=> wpjam_load($hook, $cb, ...$args) : $cb, ...$args);
213 }else{
214 $cb();
215 }
216 }
217 }
218
219 function wpjam_init($cb){
220 wpjam_load('init', is_string($cb) && str_ends_with($cb, '::init') ? wpjam_callback($cb) : $cb);
221 }
222
223 function wpjam_include($hook, $file, ...$args){
224 wpjam_load($hook, fn()=> array_map(fn($f)=> include $f, (array)$file), ...$args);
225 }
226
227 function wpjam_updater($type, $hostname, $url){
228 wpjam_hook('update_'.$type.'s_'.$hostname, ['type'=>$type, 'url'=>$url, 'bind'=>true, 'function'=>function($check, $data, $file){
229 $type = $this->type;
230 $result = $this->result ??= wpjam_remote_request($this->url);
231 $result = is_array($result) ? ($result['template']['table'] ?? $result[$type.'s']) : [];
232
233 if(isset($result['fields']) && isset($result['content'])){
234 $fields = array_column($result['fields'], 'index', 'title');
235 $item = array_find($result['content'], fn($item)=> $item['i'.$fields[$type == 'plugin' ? '插件' : '主题']] == $file);
236 $item = $item ? array_map(fn($i)=> $item['i'.$i] ?? '', $fields) : [];
237 $item = $item ? [$type=>$file, 'icons'=>[], 'banners'=>[], 'banners_rtl'=>[]]+array_map(fn($v)=> $item[$v], ['url'=>'更新地址', 'package'=>'下载地址', 'new_version'=>'版本', 'requires_php'=>'PHP最低版本', 'requires'=>'最低要求版本', 'tested'=>'最新测试版本']) : [];
238 }else{
239 $item = array_find($result ?: [], fn($item)=> $item[$type] == $file);
240 }
241
242 return $item ? $item+['slug'=>'']+($data ? ['id'=>$data['UpdateURI'], 'version'=>$data['Version'], 'requires_plugins'=>(array)($data['RequiresPlugins'] ?: [])] : []) : $check;
243 }], 10, 4);
244 }
245
246 function wpjam_assets($type, $handle, $args=[]){
247 if(!has_filter($hook = 'current_theme_supports-'.$type)){
248 add_filter($hook, fn($check, $args, $value)=> !array_diff($args, is_array($value[0]) ? $value[0] : $value), 10, 3);
249 }
250
251 $args = is_array($args) ? $args : ['src'=>$args];
252 $parts = is_admin() ? ['admin', 'wp'] : (is_login() ? ['login'] : ['wp']);
253 $parts = isset($args['for']) ? array_intersect($parts, wp_parse_list($args['for'] ?: 'wp')) : $parts;
254 $object = wpjam_hook($args+['type'=>$type, 'handle'=>$handle, 'bind'=>true, 'callback'=>function(){
255 if(($src = maybe_closure($this->src, $this->handle)) || !$this->data){
256 $src = ($src && $this->cdn ? wpjam_get_static_cdn() : '').$src;
257 $src = is_login() || is_admin() || !current_theme_supports($this->type, $this->handle) ? $src : '';
258 $args = $this->type == 'script' ? $this->pick(['in_footer', 'strategy']) : ($this->media ?? 'all');
259
260 wpjam_call('wp_'.($this->method ?: 'enqueue').'_'.$this->type, $this->handle, $src, $this->deps, $this->ver, $args);
261 }
262
263 $this->data && wpjam_call('wp_add_inline_'.$this->type, $this->handle, $this->data, $this->position ?: 'after');
264 }]);
265
266 array_walk($parts, fn($p)=> wpjam_load($p.'_enqueue_scripts', $object, ($object->priority ?? 10)));
267 }
268
269 function wpjam_script(...$args){
270 $args && $args[0] && wpjam_call(count($args) > 1 ? 'wpjam_assets' : 'wpjam_admin', 'script', ...$args);
271 }
272
273 function wpjam_style(...$args){
274 $args && $args[0] && wpjam_call((is_array($args[0]) || (str_contains($args[0], '{') && str_contains($args[0], '}'))) ? 'wpjam_admin' : 'wpjam_assets', 'style', ...$args);
275 }
276
277 // Callback
278 function wpjam_callback($cb=null, ...$args){
279 return (WPJAM_Callback::get_instance())($cb, ...$args);
280 }
281
282 function wpjam_call($cb, ...$args){
283 return wpjam_callback('', $cb, ...$args);
284 }
285
286 function wpjam_call_method($class, ...$args){
287 return $class ? wpjam_callback('method', $class, ...$args) : null;
288 }
289
290 function wpjam_call_multiple($cb, $args){
291 return array_map(fn($v)=> wpjam_call($cb, ...(array)$v), $args);
292 }
293
294 function wpjam_try($cb, ...$args){
295 return wpjam_if_error(wpjam_callback('try', wpjam_if_error($cb, 'throw'), ...$args), 'throw');
296 }
297
298 function wpjam_catch($cb, ...$args){
299 try{
300 if($cb instanceof Exception){
301 return $cb instanceof WPJAM_Exception ? $cb->get_error() : new WP_Error($cb->getCode(), $cb->getMessage());
302 }
303
304 return is_wp_error($cb) ? $cb : wpjam_callback('catch', $cb, ...$args);
305 }catch(Exception $e){
306 return wpjam_catch($e);
307 }
308 }
309
310 function wpjam_ob($cb, ...$args){
311 ob_start() && wpjam_call($cb, ...$args);
312
313 return ob_get_clean();
314 }
315
316 function wpjam_tap($value, $cb, ...$args){
317 if(is_wp_error($value)){
318 $args && wpjam_if_error($value, ...$args);
319 }else{
320 $cb && $cb($value);
321 }
322
323 return $value;
324 }
325
326 function wpjam_retry($times, $cb, ...$args){
327 do{
328 $times -= 1;
329 $result = wpjam_catch($cb, ...$args);
330 }while($result === false && $times > 0);
331
332 return $result;
333 }
334
335 function wpjam_value_callback($args, $name){
336 return wpjam_get($args, ['data', ...(array)$name]) ?? wpjam_callback('value_callback', $args, $name);
337 }
338
339 function wpjam_call_for_blog($blog_id, $cb, ...$args){
340 try{
341 $switched = (is_multisite() && $blog_id && $blog_id != get_current_blog_id()) ? switch_to_blog($blog_id) : false;
342
343 return $cb(...$args);
344 }finally{
345 $switched && restore_current_blog();
346 }
347 }
348
349 function wpjam_call_with_suppress($hooks, $cb, ...$args){
350 $hooks = wpjam_hooks('-', $hooks);
351
352 try{
353 return $cb(...$args);
354 }finally{
355 wpjam_hooks($hooks);
356 }
357 }
358
359 function wpjam_get_reflection($cb, ...$args){
360 return wpjam_callback('reflection', $cb, ...$args);
361 }
362
363 function wpjam_get_annotation($class, $key=''){
364 return wpjam_callback('annotation', $class, $key);
365 }
366
367 if(!function_exists('maybe_callback')){
368 function maybe_callback($value, ...$args){
369 return $value && is_callable($value) ? $value(...$args) : $value;
370 }
371 }
372
373 if(!function_exists('maybe_closure')){
374 function maybe_closure($value, ...$args){
375 return $value && is_closure($value) ? $value(...$args) : $value;
376 }
377 }
378
379 if(!function_exists('is_closure')){
380 function is_closure($object){
381 return $object instanceof Closure;
382 }
383 }
384
385 function wpjam_if_error($value, ...$args){
386 if($args && is_wp_error($value)){
387 if(is_closure($args[0])){
388 return array_shift($args)($value, ...$args);
389 }elseif(in_array($args[0], [null, false, [], ''], true)){
390 return $args[0];
391 }elseif($cb = ['die'=>'wp_die', 'throw'=>'wpjam_throw', 'send'=>'wpjam_send_json'][$args[0]] ?? ''){
392 $cb($value);
393 }
394 }
395
396 return $value;
397 }
398
399 function wpjam_then($value, $cb, ...$args){
400 return is_wp_error($value) ? wpjam_if_error($value, ...$args) : maybe_closure($cb, $value);
401 }
402
403 function wpjam_trap($cb, ...$args){
404 $if = array_pop($args);
405
406 return wpjam_if_error(wpjam_catch($cb, ...$args), $if);
407 }
408
409 function wpjam_db_transaction($cb, ...$args){
410 $GLOBALS['wpdb']->query("START TRANSACTION;");
411
412 try{
413 $result = $cb(...$args);
414 $error = $GLOBALS['wpdb']->last_error;
415 $error && wpjam_throw('error', $error);
416
417 $GLOBALS['wpdb']->query("COMMIT;");
418
419 return $result;
420 }catch(Exception $e){
421 $GLOBALS['wpdb']->query("ROLLBACK;");
422
423 return false;
424 }
425 }
426
427 // debug
428 function wpjam_doing_debug(){
429 $v = $_GET['debug'] ?? null;
430
431 return $v ? sanitize_key($v) : !is_null($v);
432 }
433
434 function wpjam_print_r($value){
435 if(current_user_can(is_multisite() ? 'manage_site' : 'manage_options')){
436 echo '<pre>';
437 print_r($value);
438 echo '</pre>'."\n";
439 }
440 }
441
442 function wpjam_var_dump($value){
443 if(current_user_can(is_multisite() ? 'manage_site' : 'manage_options')){
444 echo '<pre>';
445 var_dump($value);
446 echo '</pre>'."\n";
447 }
448 }
449
450 // Error
451 function wpjam_throw($code, $msg='', $data=[]){
452 throw new WPJAM_Exception(is_wp_error($code) ? $code : new WP_Error($code, $msg, $data));
453 }
454
455 function wpjam_error(...$args){
456 if(!$args || !$args[0]){
457 $method = 'get';
458 }else{
459 $method = (is_wp_error($args[0]) || is_array($args[0]) || WPJAM_Error::can(...$args)) ? 'parse' : 'update';
460 }
461
462 return ['WPJAM_Error', $method](...$args);
463 }
464
465 function wpjam_die_handler($msg, $title='', $args=[]){
466 if(is_wp_error($msg)){
467 $item = $msg;
468 }else{
469 $code = $args['code'] ?? '';
470 $data = $code && $title ? ['modal'=>['title'=>$title, 'content'=>$msg]] : [];
471 $item = !$code && !$title && is_string($msg) ? wpjam_error($msg) : [];
472 $item = $item ?: ['errcode'=>(($code ?: $title) ?: 'error'), 'errmsg'=>$msg]+$data;
473 }
474
475 wpjam_send_json($item);
476 }
477
478 // Route
479 function wpjam_route($module, $args=[], $query_var=false){
480 if(is_string($args) && class_exists($args)){
481 if(is_admin()){
482 wpjam_add('menu_page', $args);
483 wpjam_add('admin_load', $args);
484 }
485
486 $rr = $args;
487 $args = ['callback'=>$args.'::redirect'];
488 }else{
489 $rr = $args['rewrite_rule'] ?? '';
490 $args = wpjam_is_assoc_array($args) ? array_filter($args) : ['callback'=>$args];
491 }
492
493 if($rr){
494 wpjam_init(fn()=> wpjam_add('rewrite_rule', maybe_closure($rr)));
495 }
496
497 $object = wpjam_dispatch();
498
499 if($query_var && ($action = wpjam_param($module, wp_doing_ajax() ? 'data' : 'get'))){
500 $object->update_arg('query_vars['.$module.']', $action);
501 }
502
503 return $object->update_arg($module, $args+['query_var'=>$query_var]);
504 }
505
506 function wpjam_dispatch(){
507 static $object;
508
509 if(!isset($object)){
510 wpjam_hook('query_vars', '+', ['module', 'action'], 11);
511 }
512
513 return $object ??= wpjam_hook(wp_doing_ajax() ? 'admin_init' : 'parse_request', 'bind', function($wp=null){
514 $query_vars = $this->query_vars ?: [];
515
516 if($wp && ($module = $wp->query_vars['module'] ?? '')){
517 remove_action('template_redirect', 'redirect_canonical');
518
519 $query_vars[$module] = $wp->query_vars['action'] ?? '';
520 }
521
522 foreach($query_vars as $module => $action){
523 $args = $this->$module ?: [];
524
525 if($args['query_var'] ?? false){
526 $GLOBALS['wp']->set_query_var($module, $action);
527 }
528
529 if($args['callback'] ?? ''){
530 wpjam_call($args['callback'], $action, $module);
531 }
532
533 if(!is_admin()
534 && ($file = ($args['file'] ?? '') ?: apply_filters('wpjam_template', STYLESHEETPATH.'/template/'.$module.'/'.($action ?: 'index').'.php', $module, $action))
535 && is_file($file)
536 ){
537 wpjam_hook('template_include', $file);
538 }
539 }
540 }, 1);
541 }
542
543 function wpjam_add_rewrite_rule(...$args){
544 if($args && is_array($args[0])){
545 $args = $args[0];
546
547 if($args && is_array($args[0])){
548 return wpjam_call_multiple('wpjam_add_rewrite_rule', $args);
549 }
550 }
551
552 return count($args) > 2 && $args[0] ? add_rewrite_rule($GLOBALS['wp_rewrite']->root.array_shift($args), ...$args) : null;
553 }
554
555 // txt
556 function wpjam_txt($name, ...$args){
557 $object = wpjam_get_option('wpjam_verify_txts', 'object');
558
559 if($args && is_array($args[0])){
560 return $object->update_setting($name, ...$args);
561 }
562
563 if(!str_ends_with($name, '.txt')){
564 $data = $object->get_setting($name) ?: [];
565 $key = $args[0] ?? '';
566
567 return $key == 'fields' ? [
568 'name' => ['title'=>'文件名称', 'type'=>'text', 'required', 'value'=>$data['name'] ?? '', 'class'=>'all-options'],
569 'value' => ['title'=>'文件�
570 ', 'type'=>'text', 'required', 'value'=>$data['value'] ?? '']
571 ] : ($key ? ($data[$key] ?? '') : $data);
572 }
573
574 if($data = array_find($object->get_option(), fn($v)=> $v['name'] == $name)){
575 header('Content-Type: text/plain');
576 echo $data['value']; exit;
577 }
578 }
579
580 // Lifecycle
581 function wpjam_activation(...$args){
582 $args = $args ? array_reverse(array_slice($args+['', 'wp_loaded'], 0, 2)) : [];
583 $result = [wpjam_get_handler(['items_type'=>'transient', 'transient'=>'wpjam-actives']), ($args ? 'add' : 'empty')](...$args);
584
585 return $args ? $result : wpjam_call_multiple('add_action', $result);
586 }
587
588 function wpjam_loaded($action='', ...$args){
589 if($action){
590 return wpjam_load('wp_loaded', fn()=> do_action($action, ...$args));
591 }
592
593 if(!did_action('plugins_loaded')){
594 return add_action('plugins_loaded', 'wpjam_loaded', 0);
595 }
596
597 wpjam_activation();
598
599 wpjam_load_extends(get_template_directory().'/extends');
600
601 wpjam_load_extends(dirname(__DIR__).'/extends', [
602 'option' => 'wpjam-extends',
603 'sitewide' => true,
604 'title' => '扩展管理',
605 'menu_page' => ['parent'=>'wpjam-basic', 'order'=>3, 'function'=>'tab', 'tabs'=>['extends'=>['order'=>20, 'title'=>'扩展管理', 'function'=>'option']]]
606 ]);
607
608 add_filter('request', 'wpjam_parse_query_vars', 11);
609
610 add_action('loop_start', 'wpjam_loop', 1);
611 add_action('loop_end', 'wpjam_loop', 999);
612
613 wpjam_hook('pre_do_shortcode_tag', 'wpjam_shortcode', 1, 2);
614 wpjam_hook('do_shortcode_tag', 'wpjam_shortcode', 999, 2);
615
616 wpjam_hook('register_post_type_args', ['WPJAM_Post_Type', 'filter_builtin_args'], 999, 2);
617 wpjam_hook('register_taxonomy_args', ['WPJAM_Taxonomy', 'filter_builtin_args'], 999, 3);
618
619 wpjam_hooks('gettext, gettext_with_context', fn($trans, $text, ...$args)=> wpjam_translate([$trans, $text], ...$args), 10, 4);
620 }
621
622 function wpjam_loop(...$args){
623 static $object;
624 $object ??= wpjam_hook([
625 'bind' => true,
626 'queries' => [],
627 'callback' => fn($query)=> $this->update_arg('queries', $this->hook === 'loop_start' ? [...$this->queries, $query] : array_slice($this->queries, 0, -1))
628 ]);
629
630 return $args ? $object(...$args) : $object->queries;
631 }
632
633 function wpjam_is(...$args){
634 $query = ($args && is_object($args[0])) ? array_shift($args) : array_last(wpjam_loop());
635
636 return $query && ($query instanceof WP_Query) ? wpjam_query('is', $query, ...$args) : false;
637 }
638
639 function wpjam_shortcode(...$args){
640 static $object;
641 $object ??= wpjam_hook([
642 'tap' => true,
643 'bind' => true,
644 'tags' => [],
645 'callback' => fn($tag)=> $this->update_arg('tags', $this->hook === 'pre_do_shortcode_tag' ? [...$this->tags, $tag] : array_slice($this->tags, 0, -1))
646 ]);
647
648 return $args ? $object(...$args) : $object->tags;
649 }
650
651 if(!function_exists('doing_shortcode')){
652 function doing_shortcode($tag=null){
653 $tags = wpjam_shortcode();
654
655 return null === $tag ? !empty($tags) : in_array($tag, $tags, true);
656 }
657 }
658
659 // Capability
660 function wpjam_map_meta_cap($cap, $map){
661 static $object;
662 $object ??= wpjam_hook('map_meta_cap', 'bind', function($caps, $cap, $user_id, $args){
663 foreach((!in_array('do_not_allow', $caps) && $user_id) ? ($this->$cap ?: []) : [] as $v){
664 if(($v = maybe_callback($v, $user_id, $args, $cap)) || is_array($v)){
665 $caps = (array)$v;
666 }
667 }
668
669 return $caps;
670 }, 10, 4);
671
672 if($cap && $map && (is_callable($map) || wp_is_numeric_array($map))){
673 wpjam_map(wp_parse_list($cap), fn($c)=> $c && $object->update_arg($c.'[]', $map));
674 }
675 }
676
677 function wpjam_can($cap, ...$args){
678 return ($cap = maybe_closure($cap, ...$args)) ? current_user_can($cap, ...$args) : true;
679 }
680
681 // Extend
682 function wpjam_load_extends($dir, $args=[]){
683 is_dir($dir) && (new WPJAM_Extend($dir, $args))->load();
684 }
685
686 // Admin
687 function wpjam_add_menu_page(...$args){
688 if(!$args[0] || wp_is_numeric_array($args[0])){
689 return $args[0] ? array_walk($args[0], 'wpjam_add_menu_page') : null;
690 }
691
692 if(is_array($args[0])){
693 $args = $args[0];
694 }else{
695 $key = empty($args[1]['plugin_page']) ? 'menu_slug' : 'tab_slug';
696 $args = wpjam_set($args[1], $key, $args[0]);
697
698 if(!is_admin() && ($args['function'] ?? '') == 'option' && (!empty($args['sections']) || !empty($args['fields']))){
699 wpjam_register_option(($args['option_name'] ?? $args[$key]), $args);
700 }
701 }
702
703 if($type = array_find(['tab_slug'=>'tabs', 'menu_slug'=>'pages'], fn($v, $k)=> !empty($args[$k]) && !is_numeric($args[$k]))){
704 if($cap = $args['capability'] ?? ''){
705 wpjam_map_meta_cap($cap, wpjam_pull($args, 'map_meta_cap'));
706 }
707
708 if($model = $args['model'] ?? ''){
709 wpjam_hooks($model.'::add_hooks');
710 wpjam_init($model.'::init');
711
712 $cap && wpjam_map_meta_cap($cap, wpjam_callback($model.'::map_meta_cap'));
713 }
714
715 if(is_admin()){
716 if($type == 'pages'){
717 $parent = wpjam_pull($args, 'parent');
718 $key = $type.($parent ? '['.$parent.'][subs]' : '').'['.wpjam_pull($args, 'menu_slug').']';
719 $args = $parent ? $args : array_merge(wpjam_admin($key.'[]'), $args, ['subs'=>array_merge(wpjam_admin($key.'[subs][]'), $args['subs'] ?? [])]);
720 }else{
721 $key = $type.'[]';
722 }
723
724 wpjam_admin($key, $args);
725 }
726 }
727 }
728
729 if(is_admin()){
730 if(!function_exists('get_screen_option')){
731 function get_screen_option($option, $key=false){
732 if(did_action('current_screen')){
733 $screen = get_current_screen();
734 $value = in_array($option, ['post_type', 'taxonomy']) ? $screen->$option : $screen->get_option($option);
735
736 return $key ? ($value ? wpjam_get($value, $key) : null) : $value;
737 }
738 }
739 }
740
741 function wpjam_admin($key='', ...$args){
742 return is_array($key) ? wpjam_map($key, 'wpjam_admin', 'kv') : (WPJAM_Admin::get_instance())($key, ...$args);
743 }
744
745 function wpjam_chart($type='', ...$args){
746 if(wpjam_is_assoc_array($type) || $type === []){
747 return wpjam_admin('chart', WPJAM_Chart::create($type));
748 }
749
750 if(in_array($type, ['line', 'bar', 'donut'], true)){
751 return ['WPJAM_Chart', $type](...$args);
752 }
753
754 if(($object = wpjam_admin('chart')) && $type){
755 if(is_string($type)){
756 $type = ['get_parameter'=>'get_value', 'fields'=>'get_fields'][$type] ?? $type;
757 }
758
759 return in_array($type, ['validate', 'render', 'get_value', 'get_fields'], true)
760 ? $object->$type(...$args)
761 : $object->get_value($type, ...$args);
762 }
763
764 return $object;
765 }
766
767 function wpjam_add_admin_load($args){
768 wp_is_numeric_array($args) ? array_walk($args, 'wpjam_add_admin_load') : $args && wpjam_admin('load', wpjam_pull($args, 'type'), $args);
769 }
770
771 function wpjam_register_page_action($name, $args){
772 return wpjam_admin('page_actions['.$name.']', new WPJAM_Page_Action(['name'=>$name]+$args));
773 }
774
775 function wpjam_get_page_action($name){
776 return $name ? wpjam_admin('page_actions['.$name.']') : null;
777 }
778
779 function wpjam_get_page_button($name, $args=[]){
780 return wpjam_call_method(wpjam_get_page_action($name), 'get_button', $args);
781 }
782
783 function wpjam_register_list_table_action($name, $args){
784 return WPJAM_List_Table_Action::register($name, $args);
785 }
786
787 function wpjam_unregister_list_table_action($name, $args=[]){
788 return WPJAM_List_Table_Action::unregister($name, $args);
789 }
790
791 function wpjam_register_list_table_column($name, $field){
792 return WPJAM_List_Table_Column::register($name, $field);
793 }
794
795 function wpjam_unregister_list_table_column($name, $field=[]){
796 return WPJAM_List_Table_Column::unregister($name, $field);
797 }
798
799 function wpjam_register_list_table_view($name, $view=[]){
800 return WPJAM_List_Table_View::register($name, $view);
801 }
802
803 function wpjam_dashboard($action, ...$args){
804 return wpjam_admin('dashboard', $action, ...$args);
805 }
806 }
807
808 wpjam();
809
810 wpjam_loaded();
811
812 is_admin() && wpjam_admin();
813
814 load_textdomain('wpjam', dirname(__DIR__).'/template/wpjam-'.get_locale().'.l10n.php');
815
816 wpjam_route('json', 'WPJAM_JSON');
817 wpjam_route('txt', [
818 'callback' => 'wpjam_txt',
819 'rewrite_rule' => fn()=> wpjam_hook('root_rewrite_rules', '+', fn()=> $GLOBALS['wp_rewrite']->root ? [] : ['([^/]+\.txt)?$'=>'index.php?module=txt&action=$matches[1]'])
820 ]);
821
822 wpjam_error('bad_authentication', '无权限');
823 wpjam_error('access_denied', '操作受限');
824 wpjam_error('undefined_method', fn($args)=> '%s」'.(count($args) >= 2 ? '%s' : '').'未定义');
825
826 wpjam_pattern('key', '^[a-zA-Z][a-zA-Z0-9_\-]*$', '请输�
827 �英文字母、数字和 _ -,并以字母开头!');
828 wpjam_pattern('slug', '[a-z0-9_\\-]+', '请输�
829 �小写英文字母、数字和 _ -!');
830
831 wpjam_style('wpjam-static', ['src'=>'', 'method'=>'register', 'priority'=>1]);
832 wpjam_style('remixicon', ['src'=>'/remixicon/4.2.0/remixicon.min.css', 'method'=>(is_admin() ? 'enqueue' : 'register'), 'cdn'=>true, 'priority'=>1]);
833
834 wpjam_load_extends(dirname(__DIR__).'/components');
835
836
837