Changeset 3427357
- Timestamp:
- 12/25/2025 03:32:07 PM (3 months ago)
- Location:
- wpjam-basic/trunk
- Files:
-
- 18 edited
-
components/server-status.php (modified) (2 diffs)
-
extends/baidu-zz.php (modified) (2 diffs)
-
extends/bing-webmaster.php (modified) (2 diffs)
-
extends/post-type-switcher.php (modified) (1 diff)
-
includes/class-wpjam-admin.php (modified) (8 diffs)
-
includes/class-wpjam-api.php (modified) (4 diffs)
-
includes/class-wpjam-field.php (modified) (13 diffs)
-
includes/class-wpjam-list-table.php (modified) (7 diffs)
-
includes/class-wpjam-model.php (modified) (13 diffs)
-
includes/class-wpjam-user.php (modified) (2 diffs)
-
public/wpjam-compat.php (modified) (4 diffs)
-
public/wpjam-functions.php (modified) (14 diffs)
-
public/wpjam-route.php (modified) (5 diffs)
-
public/wpjam-utils.php (modified) (8 diffs)
-
readme.txt (modified) (12 diffs)
-
static/script.js (modified) (6 diffs)
-
static/style.css (modified) (1 diff)
-
wpjam-basic.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
wpjam-basic/trunk/components/server-status.php
r3356207 r3427357 240 240 'direct' => true, 241 241 'confirm' => true, 242 'callback' => fn() => opcache_reset() ? [' errmsg'=>'缓存重置成功'] : wp_die('缓存重置失败')242 'callback' => fn() => opcache_reset() ? ['notice'=>'缓存重置成功'] : wp_die('缓存重置失败') 243 243 ]); 244 244 } … … 257 257 'direct' => true, 258 258 'confirm' => true, 259 'callback' => fn() => wp_cache_flush() ? [' errmsg'=>'缓存刷新成功'] : wp_die('缓存刷新失败')259 'callback' => fn() => wp_cache_flush() ? ['notice'=>'缓存刷新成功'] : wp_die('缓存刷新失败') 260 260 ]); 261 261 } -
wpjam-basic/trunk/extends/baidu-zz.php
r3344768 r3427357 104 104 105 105 if(time() - (int)self::get_setting('baidu_zz_last') < DAY_IN_SECONDS){ 106 return $submited == -1 ? ['notice _type'=>'info', 'errmsg'=>'所有页面都已提交'] : wp_die('批量提交的配额已用完,请稍后重试');106 return $submited == -1 ? ['notice'=>'所有页面都已提交'] : wp_die('批量提交的配额已用完,请稍后重试'); 107 107 } 108 108 … … 143 143 144 144 return [ 145 'notice_type' => 'success', 146 'errmsg' => '提交成功,本次提交了'.$number.'个页面。', 145 'notice' => '提交成功,本次提交了'.$number.'个页面。', 147 146 ]; 148 147 }else{ 149 148 return [ 150 'done' => 0, 151 'errmsg' => '批量提交中,请勿关闭浏览器,本次提交了'.$number.'个页面。', 152 'notice_type' => 'info', 153 'args' => http_build_query(['offset'=>$number]) 149 'notice' => ['type'=>'info', 'message'=>'批量提交中,请勿关闭浏览器,本次提交了'.$number.'个页面。'], 150 'args' => ['offset'=>$number] 154 151 ]; 155 152 } -
wpjam-basic/trunk/extends/bing-webmaster.php
r3344768 r3427357 119 119 if(time() - (int)self::get_setting('last') < DAY_IN_SECONDS){ 120 120 if($submited == -1){ 121 return ['notice _type'=>'info', 'errmsg'=>'所有页面都已提交'];121 return ['notice'=>'所有页面都已提交']; 122 122 }else{ 123 123 wp_die('批量提交的配额已用完,请稍后重试'); … … 163 163 self::update_setting('submited', -1); 164 164 165 return [ 166 'notice_type' => 'success', 167 'errmsg' => '提交成功,本次提交了'.$number.'个页面。', 168 ]; 165 return ['notice' => '提交成功,本次提交了'.$number.'个页面。']; 169 166 }else{ 170 167 return [ 171 'done' => 0, 172 'errmsg' => '批量提交中,请勿关闭浏览器,本次提交了'.$number.'个页面。', 173 'notice_type' => 'info', 174 'args' => http_build_query(['offset'=>$number]) 168 'notice' => ['type'=>'info', 'message'=>'批量提交中,请勿关闭浏览器,本次提交了'.$number.'个页面。'], 169 'args' => ['offset'=>$number] 175 170 ]; 176 171 } -
wpjam-basic/trunk/extends/post-type-switcher.php
r3255446 r3427357 29 29 } 30 30 31 return [' errmsg'=>'未修改文章类型'];31 return ['notice'=>'未修改文章类型']; 32 32 } 33 33 -
wpjam-basic/trunk/includes/class-wpjam-admin.php
r3423058 r3427357 9 9 } 10 10 11 public function error($msg='', $type='success'){ 12 if($msg === ''){ 13 return wpjam_map($this->error ?: [], fn($e)=> wpjam_echo(wpjam_tag('div', ['is-dismissible', 'notice', 'notice-'.$e['type']], ['p', [], $e['msg']]))); 14 } 15 16 if(is_wp_error($msg)){ 17 $msg = $msg->get_error_message(); 18 $type = 'error'; 19 } 20 21 $msg && $type && $this->update_arg('error[]', compact('msg', 'type')); 22 } 23 24 public function can($capability, ...$args){ 25 return ($capability = maybe_closure($capability, ...$args)) ? current_user_can($capability, ...$args) : true; 26 } 27 28 public function button($button, $key=null, $render=null){ 29 if(wp_is_numeric_array($button)){ 30 $button = is_array($button[0]) ? $button[0] : [$button[1] => $button[0]]; 31 $button = $key ? ($button[$key] ?? wp_die('无效的提交按钮')) : $button; 32 } 33 34 if($key){ 35 $button = is_array($button) ? $button : ['text'=>$button]; 36 37 if($render){ 38 return get_submit_button($button['text'], $button['class'] ?? 'primary', $key, false); 39 } 40 }else{ 41 $render ??= true; 42 $button = wpjam_map(array_filter($button), fn($v, $k)=> $this->button($v, $k, $render)); 43 44 if($render){ 45 return $button ? wpjam_tag('p', ['submit'], implode($button)) : wpjam_tag(); 46 } 47 } 48 49 return $button; 50 } 51 52 public function notice(&$data, $default=''){ 53 if(is_array($data)){ 54 if(!empty($data['errcode']) && !empty($data['errmsg'])){ 55 return wpjam_pull($data, ['errcode', 'errmsg']); 56 } 57 58 $notice = wpjam_pull($data, 'notice'); 59 $errmsg = wpjam_pull($data, 'errmsg'); 60 } 61 62 if(empty($notice)){ 63 $notice = !empty($errmsg) && $errmsg != 'ok' ? $errmsg : $default; // 第三方接口可能返回 ok 64 } 65 66 return ['notice'=>$notice]; 67 } 68 11 69 public function chart($method, ...$args){ 12 70 if(is_object($method)){ … … 21 79 $static = wpjam_url(dirname(__DIR__), 'relative').'/static'; 22 80 23 wp_enqueue_media( $this->screen->base == 'post' ? ['post'=>wpjam_get_admin_post_id()] : []);81 wp_enqueue_media(wpjam_pick($this, ['post_id'])); 24 82 wp_enqueue_style('wpjam-style', $static.'/style.css', ['thickbox', 'wp-color-picker', 'editor-buttons'], $ver); 25 83 wp_enqueue_script('wpjam-script', $static.'/script.js', ['jquery', 'thickbox', 'wp-color-picker', 'jquery-ui-sortable', 'jquery-ui-tabs', 'jquery-ui-draggable', 'jquery-ui-autocomplete'], $ver); … … 31 89 } 32 90 33 public function notices(){34 WPJAM_Notice::render();35 36 wpjam_map($this->get_arg('error[]'), fn($e)=> wpjam_echo(wpjam_tag('div', ['is-dismissible', 'notice', 'notice-'.$e['type']], ['p', [], $e['msg']])));37 }38 39 91 public function load($screen=''){ 40 92 if($screen){ 93 if($screen->base == 'post'){ 94 $this->post_id = (int)($_GET['post'] ?? ($_POST['post_ID'] ?? 0)); 95 } 96 41 97 $this->screen = $screen; 42 98 $this->vars = ['screen_id'=>$screen->id]+array_filter(wpjam_pick($screen, ['post_type', 'taxonomy'])); … … 116 172 } 117 173 118 wpjam_trap($this->plugin_page ? [$object, 'load'] : 'WPJAM_Builtin_Page::load', $screen, fn($e)=> wpjam_add_admin_error($e));174 wpjam_trap($this->plugin_page ? [$object, 'load'] : 'WPJAM_Builtin_Page::load', $screen, fn($e)=> $this->error($e)); 119 175 120 176 add_action('admin_enqueue_scripts', [$this, 'enqueue'], 9); 121 add_action('all_admin_notices', [$this, ' notices'], 9);177 add_action('all_admin_notices', [$this, 'error'], 9); 122 178 } 123 179 … … 134 190 } 135 191 136 wpjam_add_admin_ajax('wpjam-page-action', [ 192 wpjam_ajax('wpjam-page-action', [ 193 'admin' => true, 137 194 'nonce_action' => fn($data)=> $data['page_action'] ?? '', 138 195 'callback' => fn($data)=> ($object = WPJAM_Page_Action::get($data['page_action'] ?? '')) ? $object($data['action_type']) : wpjam_page_action_compat($data), 139 196 ]); 140 197 141 wpjam_add_admin_ajax('wpjam-query', [ 198 wpjam_ajax('wpjam-query', [ 199 'admin' => true, 142 200 'fields' => ['data_type'=> ['required'=>true]], 143 201 'callback' => fn($data)=> ['items'=>($cb = [WPJAM_Data_Type::get_instance($data['data_type'], $data['query_args']), 'query_items'])[0] ? wpjam_try($cb, $data['query_args']) : []] 144 202 ]); 145 203 146 wpjam_add_admin_ajax('wpjam-upload', [ 204 wpjam_ajax('wpjam-upload', [ 205 'admin' => true, 147 206 'nonce_action' => fn($data)=> 'upload-'.$data['name'], 148 207 'callback' => fn($data)=> wpjam_upload($data['name'], ['mimes'=>$data['mimes']]) … … 220 279 $type = $button['response'] ?? ($this->response ?? $this->name); 221 280 $result = wpjam_try($cb ?: wp_die('无效的回调函数'), ...$args) ?? wp_die('回调函数没有正确返回'); 222 $result = (is_array($result) ? $result : (is_string($result) ? [($type == 'redirect' ? 'url' : 'data') => $result] : []))+['type'=>$type]; 223 $result += ($this->dismiss ? ['dismiss'=>true] : [])+($result['type'] == 'redirect' ? ['target'=>$this->target ?: '_self'] : []); 281 $result = is_array($result) ? wpjam_admin('notice', $result)+$result : (is_string($result) ? [($type == 'redirect' ? 'url' : 'data') => $result] : []); 282 $result += ['type'=>$type]+($this->dismiss ? ['dismiss'=>true] : []); 283 $result += $result['type'] == 'redirect' ? ['target'=>$this->target ?: '_self'] : []; 224 284 225 285 return apply_filters('wpjam_ajax_response', $result); … … 227 287 228 288 public function is_allowed($type=''){ 229 return wpjam_ current_user_can(($this->capability ?? ($type ? 'manage_options' : '')), $this->name);289 return wpjam_admin('can', ($this->capability ?? ($type ? 'manage_options' : '')), $this->name); 230 290 } 231 291 … … 235 295 236 296 public function button($name=null){ 237 return wpjam_ button([maybe_callback($this->submit_text, $this->name) ?? wp_strip_all_tags($this->page_title), $this->name], $name);297 return wpjam_admin('button', [maybe_callback($this->submit_text, $this->name) ?? wp_strip_all_tags($this->page_title), $this->name], $name); 238 298 } 239 299 -
wpjam-basic/trunk/includes/class-wpjam-api.php
r3423058 r3427357 10 10 } 11 11 12 return wpjam_call( is_closure($cb) ? wpjam_bind($cb, $this) : $cb, ...$args);12 return wpjam_call(wpjam_bind($cb, $this), ...$args); 13 13 } 14 14 … … 122 122 123 123 protected function prepare_item($item, $key, $action, $field=''){ 124 $field = $ this->get_items_field();124 $field = $field ?: $this->get_items_field(); 125 125 $items = $this->get_items($field); 126 126 $add = $action == 'add'; … … 760 760 return [ 761 761 'type' => (!$this->ajax || $submit == 'reset') ? 'redirect' : $submit, 762 ' errmsg' => $submit == 'reset' ? '设置已重置。' : '设置已保存。'762 'notice' => $submit == 'reset' ? '设置已重置。' : '设置已保存。' 763 763 ]; 764 764 } … … 947 947 948 948 public function page_load(){ 949 wpjam_add_admin_ajax('wpjam-option-action', [ 949 wpjam_ajax('wpjam-option-action', [ 950 'admin' => true, 950 951 'callback' => $this, 951 952 'nonce_action' => fn()=> $this->option_group, -
wpjam-basic/trunk/includes/class-wpjam-field.php
r3423058 r3427357 30 30 } 31 31 32 $key = $args[0]; 33 $args[0]= is_array($key) ? wpjam_array($key, fn($k)=> 'data-'.$k) : 'data-'.$key; 34 35 return $this->attr(...$args) ?? (wpjam_array($this->data)[$key] ?? null); 32 $args[0] = is_array($args[0]) ? wpjam_array($args[0], fn($k)=> 'data-'.$k) : 'data-'.$args[0]; 33 34 return $this->attr(...$args) ?? (wpjam_array($this->data)[$args[0]] ?? null); 36 35 } 37 36 … … 101 100 } 102 101 103 public static function accept_to_mime_types($accept){104 if($accept){105 $allowed = get_allowed_mime_types();106 $types = [];107 108 foreach(wpjam_lines($accept, ',', fn($v)=> strtolower($v)) as $v){109 if(str_ends_with($v, '/*')){110 $prefix = substr($v, 0, -1);111 $types += array_filter($allowed, fn($m)=> str_starts_with($m, $prefix));112 }elseif(str_contains($v, '/')){113 $ext = array_search($v, $allowed);114 $types += $ext ? [$ext => $v] : [];115 }elseif(($v = ltrim($v, '.')) && preg_match('/^[a-z0-9]+$/', $v)){116 $ext = array_find_key($allowed, fn($m, $ext)=> str_contains($ext, '|') ? in_array($v, explode('|', $ext)) : $v == $ext);117 $types += $ext ? wpjam_pick($allowed, [$ext]) : [];118 }119 }120 121 return $types;122 }123 }124 125 102 public static function parse($attr){ 126 103 return wpjam_array($attr, function($k, $v){ … … 170 147 $this->$key = in_array($key, ['_before', '_prepend']) ? [$value, ...$this->$key] : [...$this->$key, $value]; 171 148 } 172 173 return $this;174 149 }elseif(in_array($method, ['insert_before', 'insert_after', 'append_to', 'prepend_to'])){ 175 150 $args[0]->{str_replace(['insert_', '_to'], '', $method)}($this); 176 177 return $this;178 } 179 180 trigger_error($method);151 }else{ 152 trigger_error($method); 153 } 154 155 return $this; 181 156 } 182 157 … … 305 280 306 281 public function schema(...$args){ 307 if($args && in_array($args[0], ['validate', 'sanitize', 'prepare'])){308 if($schema = $this->schema()){309 if($schema['type'] == 'string'){310 if($args[0] == 'validate'){311 $this->pattern && !rest_validate_json_schema_pattern($this->pattern, $args[1]) && wpjam_throw('rest_invalid_pattern', wpjam_join(' ', [$this->_title, $this->custom_validity]));312 }elseif($args[0] == 'sanitize'){313 $args[1] = (string)$args[1];314 }315 }316 317 return wpjam_try('rest_'.$args[0].'_value_from_schema', $args[1], $schema, $this->_title);318 }319 320 return $args[0] == 'validate' ? true : $args[1];321 }322 323 282 if($args || isset($this->_schema)){ 324 283 return $this->attr('_schema', ...$args); … … 355 314 } 356 315 357 return $this->_schema = wpjam_parse_json_schema($value); 316 $parse = function($value) use(&$parse){ 317 foreach(wpjam_pull($value, ['enum', 'items', 'properties']) as $k => $v){ 318 if($k == 'enum'){ 319 $value[$k] = array_map(fn($iv)=> $this->sanitize($iv, $value), $v); 320 }elseif($value['type'] == ($k == 'items' ? 'array' : 'object')){ 321 $value[$k] = $k == 'items' ? $parse($v) : array_map($parse, $v); 322 } 323 } 324 325 return $value; 326 }; 327 328 return $this->_schema = $parse($value); 358 329 } 359 330 … … 470 441 471 442 if($type == 'parameter'){ 472 is_null($value) || ($value = $this->schema('sanitize', $value));473 }else{ 443 $value = is_null($value) ? null : $this->sanitize($value); 444 }else{ // 空值只需 required 验证 474 445 is_blank($value) && $this->required && wpjam_throw(($type ?: 'value').'_required', [$this->_title]); 475 446 476 $value = $this->schema($this->get_arg_by_parent('fieldset') == 'object' ? 'sanitize' : 'prepare', $value); 477 478 (is_array($value) || !is_blank($value)) && $this->schema('validate', $value); // 空值只需 required 验证 447 $schema = $this->schema() ?: []; 448 $value = [$this, $this->get_arg_by_parent('fieldset') == 'object' ? 'sanitize' : 'prepare']($value, $schema); 449 450 if((is_array($value) || !is_blank($value)) && $schema){ 451 $schema['type'] == 'string' && $this->pattern && !rest_validate_json_schema_pattern($this->pattern, $value) && wpjam_throw('rest_invalid_pattern', wpjam_join(' ', [$this->_title, $this->custom_validity])); 452 453 wpjam_try('rest_validate_value_from_schema', $value, $schema, $this->_title); 454 } 479 455 } 480 456 } … … 507 483 } 508 484 509 public function prepare($args, $type=''){ 485 public function prepare(...$args){ 486 $type = $args[1] ??= ''; 487 $value = $type ? $args[0] : null; 488 489 if(is_array($args[1])){ 490 $rule = ($schema = $args[1]) ? ([ 491 'array' => ['is_array', fn($val)=> wpjam_map($val, fn($v)=> $this->prepare($v, $schema['items']))], 492 'object' => ['is_array', fn($val)=> wpjam_map($val, fn($v, $k)=> $this->prepare($v, ($schema['properties'][$k] ?? [])))], 493 'null' => ['is_blank', fn()=> null], 494 'integer' => ['is_numeric', 'intval'], 495 'number' => ['is_numeric', 'floatval'], 496 'string' => ['is_scalar', 'strval'], 497 'boolean' => [fn($v)=> is_scalar($v) || is_null($v), 'rest_sanitize_boolean'] 498 ][$schema['type']] ?? '') : ''; 499 500 return $rule && $rule[0]($value) ? $rule[1]($value) : $value; 501 } 502 503 if($this->is('flat')){ 504 return $this->prepare_by_fields(...$args); 505 } 506 507 if(!$type){ 508 $value = $this->value_callback($args[0]); 509 } 510 510 511 if($this->is('set')){ 511 if($this->is('flat')){ 512 return $this->prepare_by_fields($args, $type); 513 } 514 515 $value = $type ? $args : $this->value_callback($args); 516 $value = $this->fields(fn($value)=> $this->prepare($this->unpack($value), 'value'), $value ?: []); 517 518 return array_filter($value, fn($v)=> !is_null($v)); 519 } 520 521 if($type == ''){ 522 return $this->prepare($this->schema('sanitize', $this->value_callback($args)), 'value'); 523 } 512 return array_filter($this->fields(fn($v)=> $this->prepare($this->unpack($v), 'value'), $value ?: []), fn($v)=> !is_null($v)); 513 } 514 515 $value = $this->sanitize($value); 524 516 525 517 if($this->is('mu')){ 526 return array_map(fn($v)=> $this->prepare_by_item($v, $type), $args);518 return array_map(fn($v)=> $this->prepare_by_item($v, 'value'), $value); 527 519 }elseif($this->is('img, image, file')){ 528 return wpjam_get_thumbnail($args, $this->size); 529 }else{ 530 return $args && $this->parse_required ? $this->parse_value_by_data_type($args) : $args; 531 } 520 return wpjam_get_thumbnail($value, $this->size); 521 } 522 523 return $value && $this->parse_required ? $this->parse_value_by_data_type($value) : $value; 524 } 525 526 public function sanitize($value, ...$args){ 527 $schema = $args[0] ?? $this->schema(); 528 529 return $schema ? wpjam_try('rest_sanitize_value_from_schema', ($schema['type'] == 'string' ? (string)$value : $value), $schema, $this->_title) : $value; 532 530 } 533 531 … … 690 688 ]); 691 689 }elseif($this->is('uploader')){ 692 $mimes = self::accept_to_mime_types($this->accept ?: 'image/*');690 $mimes = wpjam_accept_to_mime_types($this->accept ?: 'image/*'); 693 691 $exts = implode(',', array_map(fn($v)=> str_replace('|', ',', $v), array_keys($mimes))); 694 692 $params = ['_ajax_nonce'=>wp_create_nonce('upload-'.$this->key), 'action'=>'wpjam-upload', 'name'=>$this->key, 'mimes'=>$mimes]; … … 1307 1305 } 1308 1306 1309 public function formulas($action='', $key='', ...$args){ 1310 if($action == 'parse'){ 1311 if(is_array($args[0])){ 1312 return array_map(fn($f)=> array_merge($f, ['formula'=>$this->formulas('parse', $key, $f['formula'])]), $args[0]); 1313 } 1314 1307 public function formulas($key='', $path=[]){ 1308 if($key){ 1309 $fields = $this->fields; 1310 $throw = fn($key, $msg)=> wpjam_throw('invalid_formula', implode([ 1311 is_array($key) ? $msg.':' : '', 1312 implode(' → ', wpjam_map((array)$key, fn($k)=> '字段'.($fields[$k]['title'] ?? '').'「'.$k.'」'.'公式「'.$fields[$k]['formula'].'」')), 1313 is_array($key) ? '' : ','.$msg 1314 ])); 1315 1316 $path[] = in_array($key, $path) ? $throw(array_slice($path, array_search($key, $path)), '公式嵌套') : $key; 1315 1317 $depth = 0; 1316 1318 $functions = ['abs', 'ceil', 'pow', 'sqrt', 'pi', 'max', 'min', 'fmod', 'round']; 1317 1319 $signs = ['+', '-', '*', '/', '(', ')', ',', '%']; 1318 $formula = preg_split('/\s*(['.preg_quote(implode($signs), '/').'])\s*/', trim($args[0]), -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE); 1319 $throw = fn($msg)=> wpjam_throw('invalid_formula', $this->formulas('render', $key, $args[0]).'错误,'.$msg); 1320 $formula = preg_split('/\s*(['.preg_quote(implode($signs), '/').'])\s*/', trim($fields[$key]['formula']), -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE); 1320 1321 1321 1322 foreach($formula as $t){ 1322 1323 if(is_numeric($t)){ 1323 str_ends_with($t, '.') && $throw( '无效数字「'.$t.'」');1324 str_ends_with($t, '.') && $throw($key, '无效数字「'.$t.'」'); 1324 1325 }elseif(str_starts_with($t, '$')){ 1325 isset($ this->fields[substr($t, 1)]) || $throw('「'.$t.'」未定义');1326 isset($fields[substr($t, 1)]) || $throw($key, '「'.$t.'」未定义'); 1326 1327 }elseif($t == '('){ 1327 1328 $depth += 1; 1328 1329 }elseif($t == ')'){ 1329 $depth -= $depth ? 1 : $throw( '括号不匹配');1330 $depth -= $depth ? 1 : $throw($key, '括号不匹配'); 1330 1331 }else{ 1331 in_array($t, $signs) || in_array(strtolower($t), $functions) || $throw('无效的「'.$t.'」'); 1332 } 1333 } 1334 1335 return $depth ? $throw('括号不匹配') : $formula; 1336 }elseif($action == 'sort'){ 1337 if($this->get_arg('formulas['.$key.']')){ 1338 return; 1339 } 1340 1341 $path = $args[0] ?? []; 1342 $path[] = in_array($key, $path) ? wpjam_throw('invalid_formula', '公式嵌套:'.implode(' → ', wpjam_map(array_slice($path, array_search($key, $path)), fn($k)=> $this->formulas('render', $k, $this->fields[$k]['formula'])))) : $key; 1343 1344 $formula = $this->formulas('parse', $key, $this->fields[$key]['formula']); 1345 1346 wpjam_map(is_array($formula[0]) ? array_merge(...array_column($formula, 'formula')) : $formula, fn($t)=> try_remove_prefix($t, '$') && !empty($this->fields[$t]['formula']) && $this->formulas('sort', $t, $path)); 1332 in_array($t, $signs) || in_array(strtolower($t), $functions) || $throw($key, '无效的「'.$t.'」'); 1333 } 1334 } 1335 1336 $depth && $throw($key, '括号不匹配'); 1337 1338 wpjam_map($formula, fn($t)=> try_remove_prefix($t, '$') && !empty($fields[$t]['formula']) && $this->formulas($t, $path)); 1347 1339 1348 1340 $this->update_arg('formulas['.array_pop($path).']', $formula); 1349 }elseif($action == 'render'){1350 return '字段'.wpjam_get($this->fields[$key], 'title').'「'.$key.'」'.'公式「'.$args[0].'」';1351 1341 }else{ 1352 is_null($this->formulas) && wpjam_map($this->fields, fn($v, $k)=> empty($v['formula']) || $this-> formulas('sort', $k));1342 is_null($this->formulas) && wpjam_map($this->fields, fn($v, $k)=> empty($v['formula']) || $this->get_arg('formulas['.$k.']') || $this->formulas($k, [])); 1353 1343 1354 1344 return $this->formulas; … … 1357 1347 1358 1348 private function number($v){ 1359 if(is_string($v)){ 1360 $v = str_replace(',', '', trim($v)); 1361 } 1349 $v = is_string($v) ? str_replace(',', '', trim($v)) : $v; 1362 1350 1363 1351 return is_numeric($v) ? $v : false; … … 1403 1391 } 1404 1392 1405 $formulas = $this->formulas(); 1406 $args = wp_parse_args($args, ['sum'=>false, 'key'=>'']); 1407 1408 if($args['key']){ 1409 $key = $args['key']; 1410 $if_error = $this->get_arg('if_errors['.$key.']'); 1411 $formula = $formulas[$key]; 1412 $formula = is_array($formula[0]) ? (($f = array_find($formula, fn($f)=> wpjam_match($item, $f))) ? $f['formula'] : []) : $formula; 1413 1414 if(!$formula){ 1415 return ''; 1416 } 1417 1418 foreach($formula as &$t){ 1393 if(!empty($args['formula'])){ 1394 foreach($args['formula'] as &$t){ 1419 1395 if(str_starts_with($t, '$')){ 1420 1396 $k = substr($t, 1); … … 1429 1405 1430 1406 if(!isset($t)){ 1431 return $ if_error?? (isset($v) ? '!!无法计算' : '!无法计算');1407 return $args['if_error'] ?? (isset($v) ? '!!无法计算' : '!无法计算'); 1432 1408 } 1433 1409 } … … 1436 1412 1437 1413 try{ 1438 return eval('return '.implode($ formula).';');1414 return eval('return '.implode($args['formula']).';'); 1439 1415 }catch(DivisionByZeroError $e){ 1440 return $ if_error?? '!除零错误';1416 return $args['error'] ?? '!除零错误'; 1441 1417 }catch(throwable $e){ 1442 return $if_error ?? '!计算错误:'.$e->getMessage(); 1443 } 1444 } 1445 1446 if($args['sum']){ 1447 $formulas = wpjam_pick($formulas, $this->sumable[2]); 1448 } 1418 return $args['error'] ?? '!计算错误:'.$e->getMessage(); 1419 } 1420 } 1421 1422 $formulas = $this->formulas(); 1423 $formulas = empty($args['sum']) ? $formulas : wpjam_pick($formulas, $this->sumable[2]); 1449 1424 1450 1425 if($formulas){ 1451 1426 $prev = set_error_handler(function($no, $str){ 1452 if(str_contains($str , 'Division by zero')){ 1453 throw new DivisionByZeroError($str); 1454 } 1455 1456 throw new ErrorException($str, $no); 1427 throw str_contains($str , 'Division by zero') ? new DivisionByZeroError($str) : new ErrorException($str, $no); 1457 1428 }); 1458 1429 1459 1430 $item = array_diff_key($item, $formulas); 1460 $item = array_reduce(array_keys($formulas), fn($c, $k)=> wpjam_set($c, $k, $this->calc($c, ['key'=>$k]+$args)), $item); 1431 $item = wpjam_reduce($formulas, fn($c, $v, $k)=> wpjam_set($c, $k, $this->calc($c, ['error'=>$this->get_arg('if_errors['.$k.']'), 'formula'=>$v])), $item); 1432 1461 1433 $prev ? set_error_handler($prev) : restore_error_handler(); 1462 1434 } -
wpjam-basic/trunk/includes/class-wpjam-list-table.php
r3423058 r3427357 407 407 408 408 public function column_cb($item){ 409 if(($id = $this->parse_id($item)) && wpjam_ current_user_can($this->capability, $id)){409 if(($id = $this->parse_id($item)) && wpjam_admin('can', $this->capability, $id)){ 410 410 return wpjam_tag('input', ['type'=>'checkbox', 'name'=>'ids[]', 'value'=>$id, 'id'=>'cb-select-'.$id, 'title'=>'选择'.strip_tags($item[$this->get_primary_column_name()] ?? $id)]); 411 411 } … … 478 478 public function page_load(){ 479 479 if(wp_doing_ajax()){ 480 return wpjam_add_admin_ajax('wpjam-list-table-action', [ 480 return wpjam_ajax('wpjam-list-table-action', [ 481 'admin' => true, 481 482 'callback' => $this, 482 483 'nonce_action' => fn($data)=> ($object = $this->get_action($data['list_action'] ?? '')) ? $object->parse_nonce_action($data) : null … … 488 489 } 489 490 490 wpjam_trap([$this, 'prepare_items'], fn($result)=> wpjam_ad d_admin_error($result));491 wpjam_trap([$this, 'prepare_items'], fn($result)=> wpjam_admin('error', $result)); 491 492 } 492 493 … … 711 712 712 713 if($response['type'] != 'form'){ 713 $args = (in_array($type, ['submit', 'export']) ? array_filter(wpjam_pick($button, $cbs)) : [])+$args; 714 $result = $this->callback(['data'=>$data, 'fields'=>$fields, 'submit_name'=>$submit]+$args); 715 $errmsg = is_array($result) ? ($result['errmsg'] ?? '') : ''; 716 $errmsg = $errmsg && $errmsg != 'ok' ? $errmsg : ($type == 'submit' ? $button['text'].'成功' : ''); 717 718 $response['errmsg'] = $errmsg; // 第三方接口可能返回 ok 714 $args = (in_array($type, ['submit', 'export']) ? array_filter(wpjam_pick($button, $cbs)) : [])+$args; 715 $result = $this->callback(['data'=>$data, 'fields'=>$fields, 'submit_name'=>$submit]+$args); 716 $response += wpjam_admin('notice', $result, $type == 'submit' ? $button['text'].'成功' : ''); 719 717 } 720 718 721 719 if(is_array($result)){ 720 $response += wpjam_pull($result, ['args']); 721 722 722 if(array_intersect(array_keys($result), ['type', 'bulk', 'ids', 'id', 'items'])){ 723 723 $response = $result+$response; … … 755 755 756 756 if($response['type'] == 'form'){ 757 $response[' errmsg'] = '';757 $response['notice'] = ''; 758 758 } 759 759 } … … 829 829 830 830 public function is_allowed($args=[]){ 831 return $this->capability == 'read' || array_all($args && !$this->overall ? (array)$this->parse_arg($args) : [null], fn($id)=> wpjam_ current_user_can($this->capability, $id, $this->name));831 return $this->capability == 'read' || array_all($args && !$this->overall ? (array)$this->parse_arg($args) : [null], fn($id)=> wpjam_admin('can', $this->capability, $id, $this->name)); 832 832 } 833 833 … … 891 891 public function button($args, $name=null){ 892 892 if(!$name && $this->next){ 893 return wpjam_ button(['next'=>'下一步']);894 } 895 896 return wpjam_ button([maybe_callback($this->submit_text, $this->parse_arg($args), $this->name) ?? (wp_strip_all_tags($this->title) ?: $this->page_title), $this->name], $name);893 return wpjam_admin('button', ['next'=>'下一步']); 894 } 895 896 return wpjam_admin('button', [maybe_callback($this->submit_text, $this->parse_arg($args), $this->name) ?? (wp_strip_all_tags($this->title) ?: $this->page_title), $this->name], $name); 897 897 } 898 898 -
wpjam-basic/trunk/includes/class-wpjam-model.php
r3423058 r3427357 321 321 class WPJAM_Query{ 322 322 public static function query($vars, &$args=[]){ 323 if(!empty($vars['related_query'])){ 324 $post = get_post(wpjam_pull($vars, 'post') ?? get_the_ID()); 325 $type = get_post_type($post); 326 $tt_ids = []; 327 328 foreach($post ? get_object_taxonomies($type) : [] as $tax){ 329 if($terms = $tax == 'post_format' ? [] : get_the_terms($post, $tax)){ 330 $type = array_merge((array)$type, get_taxonomy($tax)->object_type); 331 $tt_ids = array_merge($tt_ids, array_column($terms, 'term_taxonomy_id')); 332 } 333 } 334 335 if(!$tt_ids){ 336 return false; 337 } 338 339 $vars += ['post_status'=>'publish', 'post__not_in'=>[$post->ID], 'post_type'=>array_unique($type), 'term_taxonomy_ids'=>wpjam_filter($tt_ids, 'unique')]; 340 } 341 323 342 $vars = self::parse_vars($vars); 324 343 … … 348 367 $query = is_object($vars) ? $vars : self::query($vars, $args); 349 368 350 if(!$ parse){351 return $query ->posts;369 if(!$query || !$parse){ 370 return $query ? $query->posts : []; 352 371 } 353 372 … … 465 484 $args += ['query'=>$query]; 466 485 467 return $ cb['wrap_callback'](implode(wpjam_map($query->posts, fn($p, $i)=> $cb['item_callback']($p->ID, $args+['i'=>$i]))), $args);486 return $query ? $cb['wrap_callback'](implode(wpjam_map($query->posts, fn($p, $i)=> $cb['item_callback']($p->ID, $args+['i'=>$i]))), $args) : ''; 468 487 } 469 488 … … 582 601 return isset($total) ? ['items'=>$items, 'total'=>$total] : $items; 583 602 }elseif(str_contains($method, '_meta')){ 584 return ($object = wpjam_get_meta_type_object($this->meta_type)) ? $object->$method(...$args) : null;603 return ($object = WPJAM_Meta_Type::get($this->meta_type)) ? $object->$method(...$args) : null; 585 604 }elseif(str_starts_with($method, 'cache_')){ 586 605 return [WPJAM_Cache::create($this), $method](...$args); … … 1267 1286 $type = $this->item_type; 1268 1287 $key = $this->primary_key; 1269 $uk = $this->unique_key;1270 1288 $title = $this->primary_title ?: 'ID'; 1271 1289 $add = $method == 'insert' || ($method == 'add' && count($args) <= 1); … … 1275 1293 $id || wpjam_throw('empty_'.($key ?: 'id'), ($key ? $title : 'ID').'不能为空'); 1276 1294 1277 $exist = isset($items[$id]);1278 1279 1295 if($method == 'set'){ 1280 if(!$exist){ 1281 $method = 'add'; 1282 } 1283 }else{ 1284 if($exist === ($method == 'add')){ 1285 wpjam_throw(($exist ? 'duplicate_' : 'invalid_').($key ?: 'id'), ($key ? $title : 'ID').'-「'.$id.'」'.($exist ? '已存在' : '不存在')); 1286 } 1296 $method = isset($items[$id]) ? 'set' : 'add'; 1297 }elseif(($exist = isset($items[$id])) === ($method == 'add')){ 1298 wpjam_throw(($exist ? 'duplicate_' : 'invalid_').($key ?: 'id'), ($key ? $title : 'ID').'-「'.$id.'」'.($exist ? '已存在' : '不存在')); 1287 1299 } 1288 1300 } … … 1295 1307 } 1296 1308 1297 $item = array_shift($args);1309 $item = $args[0]; 1298 1310 1299 1311 if($type == 'array'){ 1300 if($uk && ($add || isset($item[$uk]))){1301 $uv = $item[$uk] ?? '';1302 $blank = !$uv && !is_numeric($uv);1303 1304 if($blank || array_find($items, fn($v, $k)=> ($add || $id != $k) && $v[$uk] == $uv)){1305 wpjam_throw(($blank ? 'empty_' : 'duplicate_').$uk, ($this->unique_title ?: $uk).($blank ? '不能为空' : '不能重复'));1306 }1307 }1308 1309 1312 if($add){ 1310 1313 if(in_array($key, ['option_key', 'id'])){ … … 1314 1317 $id = $item[$key] ?? ''; 1315 1318 1316 (!$id || isset($items[$id])) && wpjam_throw(($id ? 'duplicate_' : 'empty_').$key, $title.($id ? '不能重复' : '不能为空')); 1319 (!$id || isset($items[$id])) && wpjam_throw(($id ? 'duplicate_' : 'empty_').$key, $title.($id ? '「'.$id.'」已被使用' : '不能为空')); 1320 } 1321 } 1322 1323 if(($uk = $this->unique_key) && ($add || isset($item[$uk]))){ 1324 $uv = $item[$uk] ?? ''; 1325 $blank = !$uv && !is_numeric($uv); 1326 1327 if($blank || array_find($items, fn($v, $k)=> ($add || $id != $k) && $v[$uk] == $uv)){ 1328 wpjam_throw(($blank ? 'empty_' : 'duplicate_').$uk, ($this->unique_title ?: $uk).($blank ? '不能为空' : '「'.$uv.'」已被使用')); 1317 1329 } 1318 1330 } … … 1322 1334 $add && in_array($item, $items) && wpjam_throw('duplicate_item', '不能重复'); 1323 1335 } 1336 1337 $item = $this->prepare_item ? $this->call('prepare_item_by_prop', $item, $id, $method, $items) : $item; 1324 1338 } 1325 1339 1326 1340 if(in_array($method, ['add', 'insert'])){ 1327 $this->max_items && count($items) >= $this->max_items && wpjam_throw('over_max_items', '最大允许数量:'.$this->max_items); 1328 1341 ($max = $this->max_items) && count($items) >= $max && wpjam_throw('over_max_items', '最大允许数量:'.$max); 1329 1342 $last = $this->last ?? ($method == 'add'); 1330 1343 … … 1354 1367 1355 1368 public function query_items($args){ 1356 $items = $this->parse_items();1357 1369 $s = trim(wpjam_pull($args, 's') ?: ''); 1358 1370 $number = wpjam_pull($args, 'number') ?: 50; 1359 1371 $offset = wpjam_pull($args, 'offset') ?: 0; 1360 $items = $args ? array_filter($items, fn($item)=> wpjam_matches($item, $args)) : $items; 1361 $items = $s ? array_filter($items, fn($item)=> array_any($item, fn($v)=> str_contains($v, $s))) : $items; 1362 $items = array_values($items); 1372 $items = $this->parse_items(); 1373 $items = array_values(($args || $s) ? array_filter($items, fn($item)=> (!$args || wpjam_matches($item, $args)) && (!$s || array_any($item, fn($v)=> str_contains($v, $s))) ) : $items); 1363 1374 1364 1375 return ['total'=>count($items), 'items'=>array_slice($items, $offset, $number)]; … … 1367 1378 public function parse_items($items=null){ 1368 1379 $items ??= $this->get_items(); 1369 $items = $items && is_array($items) ? wpjam_map($items, [$this, 'parse_item']) : []; 1370 $items && $this->item_type == 'array' && wpjam_lazyload($this->lazyload_key, $items); 1380 1381 if($this->item_type == 'array'){ 1382 $items = $items && is_array($items) ? wpjam_map($items, fn($v, $k)=> [$this->primary_key => $k]+(is_array($v) ? $v : [])) : []; 1383 $items && wpjam_lazyload($this->lazyload_key, $items); 1384 } 1371 1385 1372 1386 return $items; 1373 }1374 1375 public function parse_item($item, $id){1376 return $this->item_type == 'array' ? [$this->primary_key => $id]+(is_array($item) ? $item : []) : $item;1377 1387 } 1378 1388 … … 1393 1403 } 1394 1404 1395 public function exists($item, $type='unique'){1396 $items = $this->get_items();1397 $items = $this->item_type == 'array' ? ($type == 'unique' && $this->unique_key ? array_column($items, $this->unique_key) : array_keys($items)) : $items;1398 1399 return in_array($item, $items);1400 }1401 1402 1405 public function get($id){ 1403 $items = $this->get_items(); 1404 1405 return isset($items[$id]) ? $this->parse_item($items[$id], $id) : null; 1406 return ($items = wpjam_pick($this->get_items(), [$id])) ? $this->parse_items($items)[$id] : null; 1406 1407 } 1407 1408 } … … 1483 1484 } 1484 1485 } 1486 -
wpjam-basic/trunk/includes/class-wpjam-user.php
r3423058 r3427357 617 617 public function registered(){ 618 618 foreach(['login', 'bind'] as $action){ 619 wpjam_ register_ajax($this->name.'-'.$action, [619 wpjam_ajax($this->name.'-'.$action, [ 620 620 'nopriv' => true, 621 621 'callback' => [$this, 'ajax_response'] 622 622 ]); 623 623 624 wpjam_ register_ajax('get-'.$this->name.'-'.$action, [624 wpjam_ajax('get-'.$this->name.'-'.$action, [ 625 625 'nopriv' => true, 626 626 'verify' => false, … … 867 867 868 868 public static function init(){ 869 add_action('all_admin_notices', [self::class, 'render'], 9); 870 869 871 wpjam_register_page_action('delete_notice', [ 870 872 'button_text' => '删除', -
wpjam-basic/trunk/public/wpjam-compat.php
r3423058 r3427357 244 244 delete_option($from); 245 245 } 246 } 247 248 function wpjam_get_verify_txt($name, $key=''){ 249 return wpjam_txt($name, $key); 250 } 251 252 function wpjam_set_verify_txt($name, $data){ 253 return wpjam_txt($name, $data); 246 254 } 247 255 … … 918 926 } 919 927 928 function wpjam_add_admin_error($msg='', $type='success'){ 929 wpjam_admin('error', $msg, $type); 930 } 931 932 function wpjam_get_admin_post_id(){ 933 return wpjam_admin('post_id'); 934 } 935 920 936 function_alias(fn($user, $blog_id, $capability, ...$args)=> wpjam_call_for_blog($blog_id, 'user_can', $user, $capability, ...$args), 'user_can_for_blog'); 921 937 function_alias(fn($type, $value, $key='')=> ($data = wpjam_get_by_meta($type, $key, $value)) ? (object)array_first($data) : false, 'get_metadata_by_value'); … … 937 953 938 954 function_alias('is_login', 'wpjam_is_login'); 955 function_alias('wpjam_ajax', 'wpjam_register_ajax'); 939 956 function_alias('wpjam_route', 'wpjam_register_route'); 940 957 function_alias('wpjam_route', 'wpjam_register_route_module'); … … 1487 1504 trait WPJAM_Meta_Trait{ 1488 1505 public static function get_meta_type_object(){ 1489 return wpjam_get_meta_type_object(self::$meta_type);1506 return WPJAM_Meta_Type::get(self::$meta_type); 1490 1507 } 1491 1508 -
wpjam-basic/trunk/public/wpjam-functions.php
r3423058 r3427357 186 186 } 187 187 188 // Verify TXT189 function wpjam_txt(...$args){190 $object = wpjam_setting('wpjam_verify_txts');191 192 if(!$args){193 return $object;194 }195 196 if($data = array_find($object->get_option(), fn($v)=> $v['name'] == $args[0])){197 header('Content-Type: text/plain');198 echo $data['value']; exit;199 }200 }201 202 function wpjam_get_verify_txt($name, $key=''){203 $data = wpjam_txt()->get_setting($name);204 205 return $key == 'fields' ? [206 'name' => ['title'=>'文件名称', 'type'=>'text', 'required', 'value'=>$data['name'] ?? '', 'class'=>'all-options'],207 'value' => ['title'=>'文件内容', 'type'=>'text', 'required', 'value'=>$data['value'] ?? '']208 ] : ($key ? ($data[$key] ?? '') : $data);209 }210 211 function wpjam_set_verify_txt($name, $data){212 return wpjam_txt()->update_setting($name, $data);213 }214 215 188 // Meta Type 216 189 function wpjam_register_meta_type($name, $args=[]){ … … 266 239 267 240 function wpjam_add_post_type_field($post_type, $key, ...$args){ 268 ($object = WPJAM_Post_Type::get($post_type)) && wpjam_field($object, $key, ...$args);241 wpjam_field(WPJAM_Post_Type::get($post_type), $key, ...$args); 269 242 } 270 243 271 244 function wpjam_remove_post_type_field($post_type, $key){ 272 ($object = WPJAM_Post_Type::get($post_type)) && wpjam_field($object, $key);245 wpjam_field(WPJAM_Post_Type::get($post_type), $key); 273 246 } 274 247 … … 487 460 } 488 461 489 function wpjam_pagenavi($total=0, $echo=true){490 $result = '<div class="pagenavi">'.paginate_links(array_filter(['prev_text'=>'«', 'next_text'=>'»', 'total'=>$total])).'</div>';491 492 return $echo ? wpjam_echo($result) : $result;493 }494 495 462 // $number 496 463 // $post_id, $args … … 498 465 if(is_null($args)){ 499 466 $args = ['number'=>$post]; 500 $post = get_the_ID(); 501 } 502 503 $post = get_post($post); 504 $type = [get_post_type($post)]; 505 $tt_ids = []; 506 507 foreach($post ? get_object_taxonomies($type[0]) : [] as $tax){ 508 if($terms = $tax == 'post_format' ? [] : get_the_terms($post, $tax)){ 509 $type = array_merge($type, get_taxonomy($tax)->object_type); 510 $tt_ids = array_merge($tt_ids, array_column($terms, 'term_taxonomy_id')); 511 } 512 } 513 514 return $tt_ids ? wpjam_query(['related_query'=>true, 'post_status'=>'publish', 'post__not_in'=>[$post->ID], 'post_type'=>array_unique($type), 'term_taxonomy_ids'=>array_unique(array_filter($tt_ids))], $args) : false; 467 $post = null; 468 } 469 470 return wpjam_query(['post'=>$post, 'related_query'=>true], $args); 515 471 } 516 472 517 473 function wpjam_get_related_posts($post=null, $args=[], $parse=false){ 518 return wpjam_query( wpjam_get_related_posts_query($post, $args), $args, $parse);474 return wpjam_query(['post'=>$post, 'related_query'=>true], $args, $parse); 519 475 } 520 476 … … 525 481 function wpjam_get_top_viewd_posts($args=[], $parse=false){ 526 482 return wpjam_query(['posts_per_page'=>5, 'orderby'=>'meta_value_num', 'meta_key'=>'views'], $args, $parse); 483 } 484 485 function wpjam_pagenavi($total=0, $echo=true){ 486 $result = '<div class="pagenavi">'.paginate_links(array_filter(['prev_text'=>'«', 'next_text'=>'»', 'total'=>$total])).'</div>'; 487 488 return $echo ? wpjam_echo($result) : $result; 527 489 } 528 490 … … 537 499 538 500 function wpjam_add_taxonomy_field($taxonomy, $key, ...$args){ 539 ($object = WPJAM_Taxonomy::get($taxonomy)) && wpjam_field($object, $key, ...$args);501 wpjam_field(WPJAM_Taxonomy::get($taxonomy), $key, ...$args); 540 502 } 541 503 542 504 function wpjam_remove_taxonomy_field($taxonomy, $key){ 543 ($object = WPJAM_Taxonomy::get($taxonomy)) && wpjam_field($object, $key);505 wpjam_field(WPJAM_Taxonomy::get($taxonomy), $key); 544 506 } 545 507 … … 549 511 550 512 function wpjam_update_taxonomy_setting($taxonomy, $key, $value){ 551 ($object = WPJAM_Taxonomy::get($taxonomy)) && ($object->$key = $value);513 ($object = WPJAM_Taxonomy::get($taxonomy)) && ($object->$key = $value); 552 514 } 553 515 … … 619 581 } 620 582 621 // $ args, $max_depth583 // $vars, $max_depth 622 584 // $term_ids, $args 623 585 function wpjam_get_terms($vars, ...$args){ 624 586 if(is_scalar($vars) || wp_is_numeric_array($vars)){ 625 587 $terms = WPJAM_Term::get_by_ids(wp_parse_id_list($vars)); 626 $parse = $args[0] ?? false; 627 628 return $parse ? array_map('wpjam_get_term', $terms) : $terms; 629 } 630 631 $arg = $args[0] ?? null; 588 589 return $args && $args[0] ? array_map('wpjam_get_term', $terms) : $terms; 590 } 591 592 $arg = $args[0] ?? []; 632 593 $args = (is_numeric($arg) ? ['depth'=>$arg] : (is_bool($arg) ? ['parse'=>$arg] : (is_array($arg) ? $arg : [])))+wpjam_pull($vars, ['format', 'parse']); 633 594 … … 640 601 641 602 function wpjam_get_term_thumbnail_url($term=null, $size='full', $crop=1){ 642 $term ??= get_queried_object();643 $thumb = ($term = get_term($term))? (get_term_meta($term->term_id, 'thumbnail', true) ?: apply_filters('wpjam_term_thumbnail_url', '', $term)) : '';603 $term = get_term($term ?? get_queried_object()); 604 $thumb = $term ? (get_term_meta($term->term_id, 'thumbnail', true) ?: apply_filters('wpjam_term_thumbnail_url', '', $term)) : ''; 644 605 645 606 return $thumb ? wpjam_get_thumbnail($thumb, ($size ?: (wpjam_get_taxonomy_setting($term->taxonomy, 'thumbnail_size') ?: 'thumbnail')), $crop) : ''; … … 684 645 if(!function_exists('get_user_field')){ 685 646 function get_user_field($field, $user=null, $context='display'){ 686 return (($user = get_userdata($user)) && isset($user->$field)) ? sanitize_user_field($field, $user->$field, $user->ID, $context) : '';647 return (($user = get_userdata($user)) && isset($user->$field)) ? sanitize_user_field($field, $user->$field, $user->ID, $context) : ''; 687 648 } 688 649 } … … 1011 972 1012 973 function wpjam_accept_to_mime_types($accept){ 1013 return WPJAM_Attr::accept_to_mime_types($accept); 974 $allowed = get_allowed_mime_types(); 975 $types = []; 976 977 foreach(wpjam_lines($accept ?: '', ',', fn($v)=> strtolower($v)) as $v){ 978 if(str_ends_with($v, '/*')){ 979 $prefix = substr($v, 0, -1); 980 $types += array_filter($allowed, fn($m)=> str_starts_with($m, $prefix)); 981 }elseif(str_contains($v, '/')){ 982 $ext = array_search($v, $allowed); 983 $types += $ext ? [$ext => $v] : []; 984 }elseif(($v = ltrim($v, '.')) && preg_match('/^[a-z0-9]+$/', $v)){ 985 $ext = array_find_key($allowed, fn($m, $ext)=> str_contains($ext, '|') ? in_array($v, explode('|', $ext)) : $v == $ext); 986 $types += $ext ? wpjam_pick($allowed, [$ext]) : []; 987 } 988 } 989 990 return $types; 1014 991 } 1015 992 … … 1020 997 1021 998 function wpjam_wrap($text, $wrap='', ...$args){ 999 if($wrap === 'expandable'){ 1000 return wpjam_expandable($text, ...$args); 1001 } 1002 1022 1003 if((is_array($wrap) || is_closure($wrap))){ 1023 1004 $text = is_callable($wrap) ? $wrap($text, ...$args) : $text; … … 1090 1071 1091 1072 return [$object, $args ? 'update_arg' : 'delete_arg']('_fields['.$key.']', ...$args); 1092 } 1093 1094 $object = WPJAM_Field::create($field); 1095 $args = $args[0] ?? []; 1096 1097 return $args ? (isset($args['wrap_tag']) ? $object->wrap(wpjam_pull($args, 'wrap_tag'), $args) : $object->render($args)) : $object; 1098 } 1099 1100 function wpjam_button($button, $key=null, $render=null){ 1101 if(wp_is_numeric_array($button)){ 1102 $button = is_array($button[0]) ? $button[0] : [$button[1] => $button[0]]; 1103 $button = $key ? ($button[$key] ?? wp_die('无效的提交按钮')) : $button; 1104 } 1105 1106 if($key){ 1107 $button = is_array($button) ? $button : ['text'=>$button]; 1108 1109 if($render){ 1110 return get_submit_button($button['text'], $button['class'] ?? 'primary', $key, false); 1111 } 1112 }else{ 1113 $render ??= true; 1114 $button = wpjam_map(array_filter($button), fn($v, $k)=> wpjam_button($v, $k, $render)); 1115 1116 if($render){ 1117 return $button ? wpjam_tag('p', ['submit'], implode($button)) : wpjam_tag(); 1118 } 1119 } 1120 1121 return $button; 1073 }elseif(is_array($field)){ 1074 $object = WPJAM_Field::create($field); 1075 $args = $args[0] ?? []; 1076 1077 return $args ? (isset($args['wrap_tag']) ? $object->wrap(wpjam_pull($args, 'wrap_tag'), $args) : $object->render($args)) : $object; 1078 } 1122 1079 } 1123 1080 … … 1146 1103 1147 1104 // AJAX 1148 function wpjam_register_ajax($name, $args){ 1149 return WPJAM_AJAX::create($name, $args); 1105 function wpjam_ajax($name, $args){ 1106 if(empty($args['admin']) || wp_doing_ajax()){ 1107 return WPJAM_AJAX::create($name, $args); 1108 } 1150 1109 } 1151 1110 -
wpjam-basic/trunk/public/wpjam-route.php
r3423058 r3427357 107 107 108 108 function wpjam_bind($cb, $args){ 109 $object = is_object($args) ? $args : wpjam_args($args); 110 111 return $cb->bindTo($object, $object); 109 if(is_closure($cb)){ 110 $object = is_object($args) ? $args : wpjam_args($args); 111 112 return $cb->bindTo($object, $object); 113 } 114 115 return $cb; 112 116 } 113 117 … … 893 897 } 894 898 899 // txt 900 function wpjam_txt($name, ...$args){ 901 $object = wpjam_setting('wpjam_verify_txts'); 902 903 if($args && is_array($args[0])){ 904 return $object->update_setting($name, ...$args); 905 } 906 907 if(!str_ends_with($name, '.txt')){ 908 $data = $object->get_setting($name) ?: []; 909 $key = $args[0] ?? ''; 910 911 return $key == 'fields' ? [ 912 'name' => ['title'=>'文件名称', 'type'=>'text', 'required', 'value'=>$data['name'] ?? '', 'class'=>'all-options'], 913 'value' => ['title'=>'文件内容', 'type'=>'text', 'required', 'value'=>$data['value'] ?? ''] 914 ] : ($key ? ($data[$key] ?? '') : $data); 915 } 916 917 if($data = array_find($object->get_option(), fn($v)=> $v['name'] == $name)){ 918 header('Content-Type: text/plain'); 919 echo $data['value']; exit; 920 } 921 } 922 895 923 function wpjam_activation(...$args){ 896 924 $args = $args ? array_reverse(array_slice($args+['', 'wp_loaded'], 0, 2)) : []; … … 1053 1081 } 1054 1082 1055 function wpjam_current_user_can($capability, ...$args){1056 return ($capability = maybe_closure($capability, ...$args)) ? current_user_can($capability, ...$args) : true;1057 }1058 1059 1083 // Rewrite Rule 1060 1084 function wpjam_add_rewrite_rule($args){ … … 1171 1195 } 1172 1196 1173 function wpjam_add_admin_ajax($action, $args=[]){1174 wp_doing_ajax() && wpjam_register_ajax($action, ['admin'=>true]+$args);1175 }1176 1177 function wpjam_add_admin_error($msg='', $type='success'){1178 if(is_wp_error($msg)){1179 $msg = $msg->get_error_message();1180 $type = 'error';1181 }1182 1183 $msg && $type && wpjam_admin('error[]', compact('msg', 'type'));1184 }1185 1186 1197 function wpjam_add_admin_load($args){ 1187 1198 if(wp_is_numeric_array($args)){ … … 1198 1209 } 1199 1210 1200 function wpjam_get_admin_post_id(){1201 return (int)($_GET['post'] ?? ($_POST['post_ID'] ?? 0));1202 }1203 1204 1211 function wpjam_register_page_action($name, $args){ 1205 1212 return WPJAM_Page_Action::create($name, $args); -
wpjam-basic/trunk/public/wpjam-utils.php
r3423058 r3427357 14 14 // JWT 15 15 function wpjam_generate_jwt($payload, $header=[]){ 16 $header += [' alg'=>'HS256', 'typ'=>'JWT'];17 $jwt = is_array($payload) && $header['alg'] == 'HS256'? implode('.', array_map(fn($v)=> base64_urlencode(wpjam_json_encode($v)), [$header, $payload])) : '';16 $header += ['typ'=>'JWT']; // 'alg'=>'HS256' 17 $jwt = is_array($payload) ? implode('.', array_map(fn($v)=> base64_urlencode(wpjam_json_encode($v)), [$header, $payload])) : ''; 18 18 19 19 return $jwt ? $jwt.'.'.wpjam_generate_signature('hmac-sha256', $jwt) : false; … … 29 29 //nbf 时间之前不接收处理该Token 30 30 //exp 过期时间不能小于当前时间 31 if(($header['alg'] ?? '') == 'HS256' && 32 !array_any(['iat'=>'>', 'nbf'=>'>', 'exp'=>'<'], fn($v, $k)=> isset($payload[$k]) && wpjam_compare($payload[$k], $v, time())) 33 ){ 31 if(!array_any(['iat'=>'>', 'nbf'=>'>', 'exp'=>'<'], fn($v, $k)=> isset($payload[$k]) && wpjam_compare($payload[$k], $v, time()))){ 34 32 return $payload; 35 33 } … … 42 40 $header = $_SERVER['HTTP_AUTHORIZATION'] ?? ''; 43 41 44 return str_starts_with($header, 'Bearer') ? trim(substr($header, 6)) : wpjam_get_parameter($key, ['required'=>$required]);42 return try_remove_prefix($header, 'Bearer') ? trim($header) : wpjam_get_parameter($key, ['required'=>$required]); 45 43 } 46 44 … … 91 89 $length = (unpack("N", substr($text, 0, 4)))[1]; 92 90 93 if( $args &&trim(substr($text, $length + 4)) != trim($args[0])){91 if(trim(substr($text, $length + 4)) != trim($args[0])){ 94 92 return new WP_Error('invalid_appid', 'Appid 校验「'.substr($text, $length + 4).'」「'.$args[0].'」错误'); 95 93 } … … 110 108 111 109 // JSON 112 function wpjam_parse_json_schema($schema){113 if(isset($schema['enum'])){114 $schema['enum'] = array_map(fn($v)=> rest_sanitize_value_from_schema($v, wpjam_except($schema, 'enum')), $schema['enum']);115 }116 117 foreach(wpjam_pull($schema, ['items', 'properties']) as $k => $v){118 if($schema['type'] == ($k == 'items' ? 'array' : 'object')){119 $schema[$k] = $k == 'items' ? wpjam_parse_json_schema($v) : array_map('wpjam_parse_json_schema', $v);120 }121 }122 123 return $schema;124 }125 126 if(!function_exists('rest_prepare_value_from_schema')){127 function rest_prepare_value_from_schema($value, $schema){128 $rule = [129 'array' => ['is_array', fn($val)=> wpjam_map($val, fn($v)=> rest_prepare_value_from_schema($v, $schema['items']))],130 'object' => ['is_array', fn($val)=> wpjam_map($val, fn($v, $k)=> rest_prepare_value_from_schema($v, ($schema['properties'][$k] ?? '')))],131 'null' => ['is_blank', fn()=> null],132 'integer' => ['is_numeric', 'intval'],133 'number' => ['is_numeric', 'floatval'],134 'string' => ['is_scalar', 'strval'],135 'boolean' => [fn($v)=> is_scalar($v) || is_null($v), 'rest_sanitize_boolean']136 ][$schema['type']] ?? '';137 138 return $rule && $rule[0]($value) ? $rule[1]($value) : $value;139 }140 }141 142 110 function wpjam_json_encode($data){ 143 111 return wp_json_encode($data, JSON_UNESCAPED_UNICODE); … … 501 469 502 470 if($op){ 503 trigger_error('matches'); 471 trigger_error('matches'); // del 2026-03-31 504 472 return wpjam_matches($item, $args, $op); 505 473 } … … 530 498 $op = strtoupper($op); 531 499 532 if(in_array($op, ['AND', 'OR', 'NOT'])){ 533 return wpjam_array($args, fn($v, $k)=> wpjam_match($item, ...(wpjam_is_assoc_array($v) ? [$v+['key'=>$k]] : [$k, $v])), $op); 534 } 535 536 return false; 500 return in_array($op, ['AND', 'OR', 'NOT']) ? wpjam_array($args, fn($v, $k)=> wpjam_match($item, ...(wpjam_is_assoc_array($v) ? [$v+['key'=>$k]] : [$k, $v])), $op) : false; 537 501 } 538 502 … … 1306 1270 1307 1271 function wpjam_expandable($str, $num=10, $name=null){ 1308 if( count(explode("\n", $str)) > $num){1272 if(is_a($str, 'WPJAM_Tag') || count(explode("\n", $str)) > $num){ 1309 1273 static $index = 0; 1310 1274 -
wpjam-basic/trunk/readme.txt
r3423058 r3427357 3 3 Donate link: https://wpjam.com/ 4 4 Tags: WPJAM, Memcached, 性能优化 5 Requires at least: 6. 55 Requires at least: 6.7 6 6 Requires PHP: 7.4 7 Tested up to: 6. 77 Tested up to: 6.9 8 8 Stable tag: trunk 9 9 License: GPLv2 or later … … 54 54 == Changelog == 55 55 56 = 6. 8.7=56 = 6.9 = 57 57 * 新增函数 get_term_level 58 58 * 新增函数 get_term_depth … … 61 61 * 新增函数 wpjam_is,判断当前 query 是 is_main_query 并且还支持判断在哪些页面 62 62 * 新增函数 wpjam_matches,支持多条件匹配检测 63 * 新增函数 wpjam_parse_json_schema 64 * 新增函数 rest_prepare_value_from_schema 63 * 新增函数 current_shortcode 和 doing_shortcode,用于 shortcode 获取和判断 65 64 * 新增 PHP 8.5 array_first 和 array_last 兼容 66 65 * wpjam_try 和 wpjam_catch 函数新增 :: 和 -> 模式的支持 … … 70 69 * WP_Query 新增 sticky_posts 参数支持 71 70 * WPJAM_Args 新增 pick 方法 72 * WPJAM_Field 优化 attr 转换 data 的处理 73 * WPJAM_Post 优化 parse_for_json 的处理 74 * WPJAM_Taxonomy 和 WPJAM_Meta_Option 新增 show_in_posts_rest 属性。 75 * 全面优化 WPJAM_AJAX class,整合后台的 AJAX 操作 71 * WPJAM_Taxonomy 和 WPJAM_Meta_Option 新增 show_in_posts_rest 属性 76 72 * 后台 JS 新增 list_table_load 事件 77 73 * wpjam_set 支持 [] 模式新增元素 … … 134 130 * 后台 List Table 新增导出操作支持,列表 AJAX 返回更加细化 135 131 * 优化自定义文章类型和分类模式获取名称的方式 136 * 新增 Class WPJAM_Platforms - 多平台处理 137 * 新增函数 wpjam_url,根据目录获取 url 132 * 新增函数 wpjam_url - 根据目录获取 url 138 133 * 新增函数 wpjam_has_bit / wpjam_add_bit / wpjam_remove_bit - 位运算 139 134 * 新增函数:wpjam_move / wpjam_get_all_terms / wpjam_html_tag_processor / wpjam_dashboard_widget … … 145 140 * 新增函数 wpjam_generate_jwt / wpjam_verify_jwt, 实现 JWT 生成和验证 146 141 * WPJAM_Field 增加 before / after 属性,统一使用 button_field 作为各种按钮的自定义文本 147 * WPJAM_Register 增加 admin_load config 142 * WPJAM_Register 继承 WPJAM_Args 来丰富功能 143 * WPJAM_Register 新增 init 参数,支持在 WordPress init 时回调 144 * WPJAM_Register 增加 add_hooks 148 145 * WPJAM_Model 支持 meta_input 方法 149 146 * WPJAM_DB 新增 group_cache_key 属性,新增 query 方法 … … 166 163 * 新增 Trait WPJAM_Call_Trait,WPJAM_Items_Trat / WPJAM_Instance 167 164 * 新增 WPJAM_Post / WPJAM_Term 的 update_callback 方法,支持同时更新文章和分类的本身字段和自定义字段 168 * WPJAM_Register 继承 WPJAM_Args 来丰富功能169 * WPJAM_Register 增加 add_hooks 支持,支持 group config。170 165 * WPJAM_JSON 支持 data_type 接口,用于前端自动完成 171 166 * WPJAM_Field 支持 data_type 的数据源联动处理,下拉菜单,单选和复选框都支持其他选项 … … 195 190 * 函数 wpjam_register 新增 priority 参数 196 191 * 函数 wpjam_register_option 新增 field_default / menu_page 参数 197 * Class WPJAM_Register 新增 init 参数,支持在 WordPress init 时回调198 192 * 增强 Class WPJAM_Option_Setting 199 193 * 增强「文章浏览」扩展,支持批量增加浏览数 … … 248 242 * 新增 WPJAM_Field 分组打横显示功能 249 243 * 新增 Class WPJAM_Bind - 用户社交账号绑定 250 * 新增 Class WPJAM_AJAX - 统一 AJAX 处理244 * 新增 Class WPJAM_AJAX - 统一所有(包括后台) AJAX 处理 251 245 * 新增函数 wpjam_register_meta_type 252 246 * 新增函数 wpjam_register_bind … … 265 259 * 跳过其他版本直接升级到 5.6 / WordPress 保持一致 266 260 * CDN 文件扩展设置和媒体库对应 267 * 调用 save_post 改成调用 wp_after_insert_post268 261 269 262 = 5.2 = … … 271 264 * 新增函数 wpjam_register_json 自定义 API 接口 272 265 * wpjam_add_menu_page 支持 load_callback 参数 273 * form 页面支持 summary274 266 * wpjam_register_option 支持自定义 update_callback 和 reset 选项 275 267 … … 380 372 = 3.0 = 381 373 * 基于 PHP 7.2 进行代码重构,效率更高,更加快速 382 * 全 AJAX操作后台374 * 全 AJAX 操作后台 383 375 * 新增「简单SEO」扩展 384 376 * 新增「短代码」扩展 -
wpjam-basic/trunk/static/script.js
r3396132 r3427357 148 148 } 149 149 150 if(!args){ 150 if(args){ 151 if(args.action_type == 'submit'){ 152 $el = $el.is(':submit') ? $el : this.find(':submit').first().focus(); 153 } 154 }else{ 151 155 args = { 152 156 action_type: this.is('form') ? 'submit' : (this.data('direct') ? 'direct' : 'form'), … … 298 302 299 303 if(type == 'option'){ 300 data.type == 'save' && wpjam.add_notice(data. errmsg, 'success');304 data.type == 'save' && wpjam.add_notice(data.notice); 301 305 302 306 $('body').wpjam_form().trigger('option_action_success', data); 303 307 }else if(type == 'page'){ 304 308 if(!['form', 'append', 'redirect'].includes(data.type)){ 305 data. done === 0&& setTimeout(()=> this.wpjam_action(type, _.extend({}, args, {data: data.args})), 400);309 data.args && setTimeout(()=> this.wpjam_action(type, _.extend({}, args, {data: data.args})), 400); 306 310 307 311 args.action_type == 'submit' && $('#wpjam_form').length && data.form && $('#wpjam_form').html(data.form); 308 312 309 wpjam.add_notice(data. errmsg || args.page_title+'成功', data.notice_type || 'success');313 wpjam.add_notice(data.notice || args.page_title+'成功'); 310 314 } 311 315 … … 334 338 } 335 339 }else if(!['form', 'append', 'redirect'].includes(data.type)){ 340 data.args && setTimeout(()=> ($('#TB_window').length ? $('#list_table_action_form') : this).wpjam_action(type, _.extend({}, args, {data: data.args})), 400); 341 336 342 data.type == 'list' && data.list_action == 'delete' && list_table.delete_row(args.id); 337 343 … … 437 443 438 444 add_notice: function(notice, type){ 445 if(typeof notice === 'object'){ 446 type = notice.type; 447 notice = notice.message; 448 } 449 439 450 if(notice){ 440 let $notice = $('<div class="notice notice-'+ type+' is-replaceable is-dismissible"><p><strong>'+notice+'</strong></p></div>');451 let $notice = $('<div class="notice notice-'+(type || 'success')+' is-replaceable is-dismissible"><p><strong>'+notice+'</strong></p></div>'); 441 452 442 453 if($('#TB_ajaxContent').length){ … … 1036 1047 1037 1048 (modal && data.form) && wpjam.add_modal(data); 1038 (modal || args.action_type != 'submit') && wpjam.add_notice(data. errmsg, 'success');1049 (modal || args.action_type != 'submit') && wpjam.add_notice(data.notice); 1039 1050 1040 1051 if(data.type == 'list'){ … … 1155 1166 }); 1156 1167 1168 $(document).on('heartbeat-send', (e, data)=> wpjam.query_data && $.extend(data, wpjam.query_data)); 1169 1157 1170 wpjam.load(); 1158 1171 }); -
wpjam-basic/trunk/static/style.css
r3396132 r3427357 23 23 .expandable-container{display:flex; flex-direction:column-reverse; align-items:flex-start;} 24 24 .expandable-container .inner{max-height:12em; margin-bottom:1em; overflow:hidden; transition:max-height 1s ease;} 25 .expandable-container .inner .row-actions{display:none;} 25 26 .expandable-container input:checked + label + .inner{max-height:none; margin-bottom:0;} 27 .expandable-container input:checked + label + .inner .row-actions{display:initial;} 26 28 .expandable-container input{display:none;} 27 29 .expandable-container label:before{font-family:remixicon !important; font-style:normal; content:"展开\f2e0";} -
wpjam-basic/trunk/wpjam-basic.php
r3423059 r3427357 4 4 Plugin URI: https://blog.wpjam.com/project/wpjam-basic/ 5 5 Description: WPJAM 常用的函数和接口,屏蔽所有 WordPress 不常用的功能。 6 Version: 6. 8.87 Requires at least: 6. 68 Tested up to: 6. 86 Version: 6.9 7 Requires at least: 6.7 8 Tested up to: 6.9 9 9 Requires PHP: 7.4 10 10 Author: Denis
Note: See TracChangeset
for help on using the changeset viewer.