Changeset 3320942
- Timestamp:
- 07/02/2025 05:27:16 AM (9 months ago)
- Location:
- wpjam-basic/trunk
- Files:
-
- 23 edited
-
components/wpjam-cdn.php (modified) (1 diff)
-
components/wpjam-custom.php (modified) (2 diffs)
-
extends/mobile-theme.php (modified) (2 diffs)
-
extends/wpjam-postviews.php (modified) (2 diffs)
-
extends/wpjam-seo.php (modified) (5 diffs)
-
extends/wpjam-smtp.php (modified) (1 diff)
-
includes/class-wpjam-admin.php (modified) (19 diffs)
-
includes/class-wpjam-api.php (modified) (4 diffs)
-
includes/class-wpjam-args.php (modified) (20 diffs)
-
includes/class-wpjam-field.php (modified) (3 diffs)
-
includes/class-wpjam-list-table.php (modified) (16 diffs)
-
includes/class-wpjam-model.php (modified) (5 diffs)
-
includes/class-wpjam-post.php (modified) (3 diffs)
-
includes/class-wpjam-setting.php (modified) (5 diffs)
-
includes/class-wpjam-term.php (modified) (2 diffs)
-
includes/class-wpjam-user.php (modified) (1 diff)
-
public/wpjam-compat.php (modified) (1 diff)
-
public/wpjam-functions.php (modified) (2 diffs)
-
public/wpjam-route.php (modified) (4 diffs)
-
public/wpjam-utils.php (modified) (6 diffs)
-
readme.txt (modified) (2 diffs)
-
static/form.js (modified) (2 diffs)
-
wpjam-basic.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
wpjam-basic/trunk/components/wpjam-cdn.php
r3315366 r3320942 98 98 99 99 if(in_array($name, ['exts', 'dirs'])){ 100 $value = $value ? array_filter(array_map('trim', $value)) : [];100 $value = array_filter(array_map('trim', $value ?: [])); 101 101 102 102 if($name == 'exts'){ -
wpjam-basic/trunk/components/wpjam-custom.php
r3310594 r3320942 12 12 'head' => ['title'=>'前台 Head 代码', 'type'=>'textarea'], 13 13 'footer' => ['title'=>'前台 Footer 代码', 'type'=>'textarea'], 14 'custom' => ['title'=>'文章页代码', 'type'=>'fields et', 'fields'=>[15 'custom_post' => ['label'=>' 开启单独设置每篇文章head 和 Footer 代码。'],16 'list_table' => ['show_if'=>['custom_post', 1], 'after'=>'在文章列表页设置 ', 'options'=>[0=>'不支持', 1=>'支持', 'only'=>'只允许']]14 'custom' => ['title'=>'文章页代码', 'type'=>'fields', 'fields'=>[ 15 'custom_post' => ['label'=>'每篇文章单独设置 head 和 Footer 代码。'], 16 'list_table' => ['show_if'=>['custom_post', 1], 'after'=>'在文章列表页设置。', 'options'=>[0=>'不支持', 1=>'支持', 'only'=>'只允许']] 17 17 ]] 18 18 ]], … … 115 115 'model' => 'WPJAM_Custom', 116 116 'site_default' => true, 117 'menu_page' => ['parent'=>'wpjam-basic', ' menu_slug'=>'wpjam-custom', 'position'=>1, 'function'=>'option', 'summary'=>__FILE__]117 'menu_page' => ['parent'=>'wpjam-basic', 'position'=>1, 'function'=>'option', 'summary'=>__FILE__] 118 118 ]); -
wpjam-basic/trunk/extends/mobile-theme.php
r3310594 r3320942 9 9 public static function get_sections(){ 10 10 $options = array_map(fn($v)=> $v->get('Name'), wp_get_themes(['allowed'=>true])); 11 $options = wp _array_slice_assoc($options, [get_stylesheet()])+$options;11 $options = wpjam_pick($options, [get_stylesheet()])+$options; 12 12 13 return ['enhance'=>['fields'=>['mobile_stylesheet'=>['title'=>'移动主题', 'options'=>$options]]]];13 return wpjam_set('enhance.fields.mobile_stylesheet', ['title'=>'移动主题', 'options'=>$options]); 14 14 } 15 15 16 16 public static function builtin_page_load(){ 17 $object = wpjam_register_page_action('set_mobile_stylesheet', [ 17 $mobile = wpjam_basic_get_setting('mobile_stylesheet'); 18 $button = wpjam_register_page_action('set_mobile_stylesheet', [ 18 19 'button_text' => '移动主题', 19 20 'class' => 'mobile-theme button', … … 22 23 'response' => 'redirect', 23 24 'callback' => fn()=> WPJAM_Basic::update_setting('mobile_stylesheet', wpjam_get_data_parameter('stylesheet')) 24 ]) ;25 ])->get_button(['data'=>['stylesheet'=>'slug']]); 25 26 26 wpjam_admin('script', <<<'EOD'27 wpjam_admin('script', sprintf(<<<'EOD' 27 28 if(wp && wp.Backbone && wp.themes && wp.themes.view.Theme){ 28 let original_render = wp.themes.view.Theme.prototype.render; 29 let mobile = ".wpjam_json_encode(wpjam_basic_get_setting('mobile_stylesheet'))."; 30 let action = ".wpjam_json_encode($object->get_button())."; 29 let render = wp.themes.view.Theme.prototype.render; 30 31 31 wp.themes.view.Theme.prototype.render = function(){ 32 original_render.apply(this, arguments);32 render.apply(this, arguments); 33 33 34 let stylesheet = this.$el.data('slug'); 35 36 if(stylesheet == mobile){ 37 this.$el.find('.theme-actions').append('<span class="mobile-theme button button-primary">移动主题</span>'); 38 }else{ 39 this.$el.find('.theme-actions').append(action.replace('data-nonce=', 'data-data="stylesheet='+stylesheet+'" data-nonce=')); 40 } 34 this.$el.find('.theme-actions').append(this.$el.data('slug') == %s ? '<span class="mobile-theme button button-primary">移动主题</span>' : (%s).replace('slug', this.$el.data('slug'))); 41 35 }; 42 36 } 43 EOD );37 EOD, wpjam_json_encode($mobile), wpjam_json_encode($button))); 44 38 45 39 // wpjam_admin('style', '.mobile-theme{position: absolute; top: 45px; right: 18px;}'); -
wpjam-basic/trunk/extends/wpjam-postviews.php
r3305886 r3320942 143 143 144 144 // 不指定 post_type ,默认查询 post,这样custom post type 的文章页面就会显示 404 145 add_action('pre_get_posts', fn($query)=> $query->get('module') == 'postviews' ? $query->set('post_type', 'any') : null);145 // add_action('pre_get_posts', fn($query)=> $query->get('module') == 'postviews' ? $query->set('post_type', 'any') : null); 146 146 147 147 $begin = (int)wpjam_basic_get_setting('views_begin'); … … 151 151 $views = rand(min($begin, $end), max($begin, $end)); 152 152 153 add_action('wp_after_insert_post', fn($post_id, $post, $update)=> (!$update && is_post_type_viewable($post->post_type)) ? update_post_meta($post_id, 'views', $views) : null, 999, 3);153 add_action('wp_after_insert_post', fn($post_id, $post, $update)=> (!$update && $post->post_type != 'attachment' && is_post_type_viewable($post->post_type)) ? update_post_meta($post_id, 'views', $views) : null, 999, 3); 154 154 } 155 155 } -
wpjam-basic/trunk/extends/wpjam-seo.php
r3273174 r3320942 64 64 } 65 65 66 public static function get_value($type='title', $output='html'){ 66 public static function get_value($type='title'){ 67 if($type == 'meta'){ 68 return array_filter(wpjam_fill(['description', 'keywords'], fn($k)=> self::get_value($k))); 69 } 70 67 71 if(is_front_page()){ 68 72 if(get_query_var('paged') < 2){ … … 88 92 $value = get_the_excerpt(); 89 93 }elseif($type == 'keywords'){ 90 $tags = get_the_tags(); 91 $value = $tags ? implode(',', wp_list_pluck($tags, 'name')) : ''; 94 $value = ($tags = get_the_tags()) ? implode(',', wp_list_pluck($tags, 'name')) : ''; 92 95 } 93 96 } … … 95 98 96 99 if(!empty($value)){ 97 $value = wpjam_get_plain_text($value); 98 99 if($type == 'title'){ 100 $value = esc_textarea($value); 101 102 return $output == 'html' ? '<title>'.$value.'</title>'."\n" : $value; 103 }else{ 104 $value = esc_attr($value); 105 106 return $output == 'html' ? "<meta name='{$type}' content='{$value}' />\n" : $value; 107 } 100 $value = wp_strip_all_tags($value, true); 101 102 return $type == 'title' ? esc_textarea($value) : "<meta name='{$type}' content='".esc_attr($value)."' />\n"; 108 103 } 109 104 } … … 161 156 } 162 157 163 public static function on_wp_head(){158 public static function filter_html($html){ 164 159 $title = self::get_value('title'); 165 $meta = array_filter(wpjam_fill(['description', 'keywords'], fn($k)=> self::get_value($k))); 166 160 $title = $title ? '<title>'.$title.'</title>' : ''; 161 162 if($meta = self::get_value('meta')){ 163 $title = ($title ?: '\1')."\n".implode($meta); 164 $html = wpjam_preg_replace('#<meta\s+name=([\'"])('.implode('|', array_keys($meta)).')\1(.*?)\/>#is', '', $html); 165 } 166 167 return $title ? wpjam_preg_replace('#(<title>[^<]*<\/title>)#is', $title, $html) : $html; 168 } 169 170 public static function add_hooks(){ 167 171 if(self::get_setting('unique')){ 168 if($meta){ 169 add_filter('wpjam_html', fn($html)=> wpjam_preg_replace('#<meta\s+name=([\'"])('.implode('|', array_keys($meta)).')\1(.*?)\/>#is', '', $html)); 170 171 $title = ($title ?: '\1')."\n".implode($meta); 172 } 173 174 if($title){ 175 add_filter('wpjam_html', fn($html)=> wpjam_preg_replace('#(<title>[^<]*<\/title>)#is', $title, $html)); 176 } 177 }else{ 178 echo implode($meta); 179 } 180 } 181 182 public static function add_hooks(){ 183 add_action('wp_head', [self::class, 'on_wp_head']); 172 add_filter('wpjam_html', [self::class, 'filter_html']); 173 }else{ 174 add_action('wp_head', fn()=> wpjam_echo(implode(self::get_value('meta')))); 175 } 184 176 185 177 add_filter('robots_txt', fn($output, $public)=> $output.($public ? self::get_setting('robots') : ''), 10, 2); 186 add_filter('document_title', fn($title)=> self::get_value('title' , '') ?: $title);178 add_filter('document_title', fn($title)=> self::get_value('title') ?: $title); 187 179 188 180 if(self::get_setting('sitemap') == 0){ … … 216 208 217 209 wpjam_register_option('wpjam-seo', [ 218 'title' => 'SEO设置', 219 'model' => 'WPJAM_SEO', 220 'flush_rewrite_rules' => true, 221 'plugin_page' => 'wpjam-seo', 222 'current_tab' => 'seo', 223 'menu_page' => ['tab_slug'=>'seo', 'order'=>20, 'summary'=>__FILE__] 210 'title' => 'SEO设置', 211 'model' => 'WPJAM_SEO', 212 'plugin_page' => 'wpjam-seo', 213 'current_tab' => 'seo', 214 'menu_page' => ['tab_slug'=>'seo', 'order'=>20, 'summary'=>__FILE__] 224 215 ]); -
wpjam-basic/trunk/extends/wpjam-smtp.php
r3236921 r3320942 9 9 public static function get_fields(){ 10 10 return [ 11 'smtp_setting' => ['title'=>'SMTP 设置', 'type'=>'fieldset', 'fields'=>[12 'host' => ['title'=>' 地址', 'type'=>'text', 'class'=>'all-options', 'value'=>'smtp.qq.com'],13 ' ssl' => ['title'=>'发送协议', 'type'=>'text', 'class'=>'', 'value'=>'ssl'],14 'p ort' => ['title'=>'SSL端口', 'type'=>'number', 'class'=>'', 'value'=>'465'],15 ' user' => ['title'=>'邮箱账号', 'type'=>'email', 'class'=>'all-options'],16 'p ass' => ['title'=>'邮箱密码', 'type'=>'password', 'class'=>'all-options'],11 'smtp_setting' => ['title'=>'SMTP 设置', 'type'=>'fieldset', 'fields'=>[ 12 'host' => ['title'=>'SMTP地址', 'type'=>'text', 'class'=>'', 'value'=>'smtp.qq.com'], 13 'user' => ['title'=>'邮箱账号', 'type'=>'email', 'class'=>''], 14 'pass' => ['title'=>'邮箱密码', 'type'=>'password', 'class'=>''], 15 'ssl' => ['title'=>'发送协议', 'type'=>'text', 'class'=>'', 'value'=>'ssl'], 16 'port' => ['title'=>'SSL端口', 'type'=>'number', 'class'=>'', 'value'=>'465'], 17 17 ]], 18 18 'mail_from_name' => ['title'=>'发送者姓名', 'type'=>'text', 'class'=>''], 19 'reply_to_mail' => ['title'=>'回复地址', 'type'=>'email','class'=>' all-options', 'description'=>'不填则用户回复使用SMTP设置中的邮箱账号']19 'reply_to_mail' => ['title'=>'回复地址', 'type'=>'email','class'=>'', 'description'=>'不填则用户回复使用SMTP设置中的邮箱账号'] 20 20 ]; 21 21 } -
wpjam-basic/trunk/includes/class-wpjam-admin.php
r3315366 r3320942 20 20 if(in_array($key, ['script', 'style'])){ 21 21 $key .= '[]'; 22 $value = is_array($value) ? implode("\n", $value) : $value; 22 23 }elseif($key == 'pages[]'){ 23 24 $slug = wpjam_pull($value, 'menu_slug'); … … 28 29 $value = array_merge($this->get_arg($key, []), $value, ['subs'=>array_merge($this->get_arg($key.'[subs]', []), $value['subs'])]); 29 30 }elseif($key == 'query_data'){ 30 $value = wpjam_map($value, fn($v)=> is_null($v) ? $v : (is_array($v) ? wp_die('query_data 不能为数组') : sanitize_textarea_field($v))); 31 $value = array_merge($this->get_arg($key, []), $value); 31 $value = array_merge($this->get_arg($key, []), array_map(fn($v)=> is_null($v) ? $v : (is_array($v) ? wp_die('query_data 不能为数组') : sanitize_textarea_field($v)), $value)); 32 32 } 33 33 … … 60 60 61 61 if($this->script){ 62 wp_add_inline_script('wpjam-script', "jQuery(function($){".preg_replace('/^/m', "\t", "\n".implode("\n\n", array_map(fn($v)=> implode("\n\n", (array)$v), $this->script)))."\n});");62 wp_add_inline_script('wpjam-script', "jQuery(function($){".preg_replace('/^/m', "\t", "\n".implode("\n\n", $this->script))."\n});"); 63 63 } 64 64 65 65 if($this->style){ 66 wp_add_inline_style('wpjam-style', "\n".implode("\n\n", array_ map(fn($v)=> implode("\n", (array)$v), array_filter($this->style))));66 wp_add_inline_style('wpjam-style', "\n".implode("\n\n", array_filter($this->style))); 67 67 } 68 68 } … … 146 146 }), 'order', 'desc', 10) as $load){ 147 147 if(!empty($load['page_file'])){ 148 wpjam_map((array)$load['page_file'], fn($file)=> is_file($file) ? include $file : null); 148 foreach((array)$load['page_file'] as $file){ 149 is_file($file) && include $file; 150 } 149 151 } 150 152 … … 185 187 $builtins = wpjam_array($GLOBALS['admin_page_hooks'], fn($k, $v)=> str_contains($k, '.php') ? [(str_starts_with($k, 'edit.php?') && $v != 'pages') ? wpjam_get_post_type_setting($v, 'plural') : $v, $k] : null); 186 188 187 $builtins += array_filter(wpjam_map(['themes'=>'appearance', 'options'=>'settings', 'users'=>'profile'], fn($v)=> $builtins[$v] ?? ''));189 $builtins += wpjam_array(['themes'=>'appearance', 'options'=>'settings', 'users'=>'profile'], fn($k, $v)=> [$k, $builtins[$v] ?? null], true); 188 190 } 189 191 … … 231 233 if(wp_doing_ajax()){ 232 234 wpjam_add_admin_ajax('wpjam-page-action', [ 233 'callback' => ['WPJAM_Page_Action', 'ajax_response'], 234 'fields' => ['page_action'=>[], 'action_type'=>[]] 235 'callback' => ['WPJAM_Page_Action', 'ajax_response'], 236 'fields' => ['page_action'=>[], 'action_type'=>[]], 237 'nonce_action' => fn($data)=> $data['page_action'] ?? null 235 238 ]); 236 239 237 240 wpjam_add_admin_ajax('wpjam-upload', [ 238 'callback' => ['WPJAM_Field', 'ajax_upload'] 241 'callback' => fn($data)=> wpjam_upload($data['name'], ['mimes'=>$data['mimes']]), 242 'nonce_action' => fn($data)=> 'upload-'.$data['name'] 239 243 ]); 240 244 … … 260 264 public function is_allowed($type=''){ 261 265 return wpjam_current_user_can(($this->capability ?? ($type ? 'manage_options' : '')), $this->name); 262 }263 264 public function create_nonce(){265 return wp_create_nonce($this->name);266 }267 268 public function verify_nonce(){269 return check_ajax_referer($this->name, false, false);270 266 } 271 267 … … 284 280 'page_title' => $title 285 281 ]; 286 }287 288 if(!$this->verify_nonce()){289 wp_die('invalid_nonce');290 282 } 291 283 … … 324 316 $button = is_array($button) ? $button : [$this->name => $button]; 325 317 326 return wpjam_parse_submit_button($button, $name);318 return WPJAM_AJAX::parse_submit_button($button, $name); 327 319 } 328 320 … … 349 341 'id' => $this->form_id ?: 'wpjam_form', 350 342 'data' => $this->generate_data_attr([], 'form') 351 ])->append( ...(($button = $this->get_submit_button()) ? ['p', ['submit'], $button] : ['']));343 ])->append($this->get_submit_button()); 352 344 } 353 345 } … … 363 355 return [ 364 356 'action' => $this->name, 365 'nonce' => $this->create_nonce()366 ] + ($type == 'button' ? [357 'nonce' => wp_create_nonce($this->name) 358 ] + ($type == 'button' ? wpjam_pick($this, ['direct', 'confirm'])+[ 367 359 'title' => $this->page_title ?: $this->button_text, 368 360 'data' => wp_parse_args(($args['data'] ?? []), ($this->data ?: [])), 369 'direct' => $this->direct,370 'confirm' => $this->confirm371 361 ] : []); 372 362 } … … 547 537 } 548 538 549 wpjam_map((array)$this->pull(($this->tab_slug ? 'tab' : 'page').'_file') ?: [], fn($f)=> include $f); 539 foreach((array)$this->pull(($this->tab_slug ? 'tab' : 'page').'_file') as $f){ 540 include($f); 541 } 550 542 } 551 543 … … 630 622 wpjam_admin('load'); 631 623 }elseif($type){ 632 $object = $object ?:$this->page_object($type, $name);624 $object ??= $this->page_object($type, $name); 633 625 $hook = 'load-'.wpjam_admin('page_hook'); 634 626 … … 654 646 private function preprocess($type, $name){ 655 647 $class = ['form'=>'WPJAM_Page_Action', 'option'=>'WPJAM_Option_Setting'][$type] ?? ''; 656 $object = $class ? $class::get($name) : '';648 $object = $class ? $class::get($name) : null; 657 649 658 650 if($object){ … … 722 714 } 723 715 724 wpjam_map(['admin_head', 'admin_footer'], fn($v)=> ($cb = [$model, $v]) && method_exists(...$cb) ? add_action($v, $cb) : null); 716 foreach(['admin_head', 'admin_footer'] as $v){ 717 method_exists($model, $v) && add_action($v, [$model, $v]); 718 } 725 719 726 720 return new WPJAM_List_Table($args+array_filter([ … … 794 788 if($method == 'callback'){ // 只有 POST 方法提交才处理,自动草稿、自动保存和预览情况下不处理 795 789 if($_SERVER['REQUEST_METHOD'] != 'POST' 796 || get_post_status($ post_id) == 'auto-draft'790 || get_post_status($args[0]) == 'auto-draft' 797 791 || (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) 798 792 || (!empty($_POST['wp-preview']) && $_POST['wp-preview'] == 'dopreview') … … 877 871 878 872 if($label = in_array($typenow, ['post', 'page', 'attachment']) ? '' : $object->labels->name){ 879 add_filter('post_updated_messages', fn($ms)=> $ms+[$typenow=> wpjam_map($ms['post'], fn($m)=> str_replace('文章', $label, $m))]);873 add_filter('post_updated_messages', fn($ms)=> $ms+[$typenow=> array_map(fn($m)=> str_replace('文章', $label, $m), $ms['post'])]); 880 874 } 881 875 … … 900 894 901 895 if($base == 'edit-tags'){ 902 wpjam_map(['slug', 'description'], fn($k)=> $object->supports($k) ? null : wpjam_unregister_list_table_column($k)); 896 foreach(['slug', 'description'] as $sup){ 897 !$object->supports($sup) && wpjam_unregister_list_table_column($k); 898 } 903 899 904 900 wpjam_unregister_list_table_action('inline hide-if-no-js'); … … 1094 1090 } 1095 1091 1096 $parser = fn($item)=> empty($cbs) ? $item : array_merge($item, wpjam_map($cbs, fn($cb)=> $cb($item)));1092 $parser = fn($item)=> empty($cbs) ? $item : array_merge($item, array_map(fn($cb)=> $cb($item), $cbs)); 1097 1093 $data = $total = []; 1098 1094 -
wpjam-basic/trunk/includes/class-wpjam-api.php
r3315366 r3320942 133 133 134 134 public static function on_plugins_loaded(){ 135 array_map(fn($active)=> $active && count($active) >= 2 ? add_action(...$active) : null, self::activation());135 array_map(fn($active)=> $active && count($active) >= 2 && add_action(...$active), self::activation()); 136 136 array_map(fn($filter)=> add_filter($filter, [self::get_instance(), 'filter_'.$filter], 11), ['query_vars', 'request']); 137 137 … … 407 407 public function get_tabbar($page_key=''){ 408 408 if(!$page_key){ 409 return wpjam_array($this->get_paths(), fn($k)=> ($v = $this->get_tabbar($k)) ? [$k, $v] : null);409 return wpjam_array($this->get_paths(), fn($k)=> [$k, $this->get_tabbar($k)], true); 410 410 } 411 411 … … 417 417 public function get_page($page_key=''){ 418 418 if($page_key){ 419 return ($path = $this->get_item($page_key.'.path')) ? explode('?', $path)[0] : '';420 } 421 422 return wpjam_array($this->get_paths(), fn($k)=> ($v = $this->get_page($k)) ? [$k, $v] : null);419 return ($path = $this->get_item($page_key.'.path')) ? explode('?', $path)[0] : null; 420 } 421 422 return wpjam_array($this->get_paths(), fn($k)=> [$k, $this->get_page($k)], true); 423 423 } 424 424 … … 1406 1406 }else{ 1407 1407 return [ 1408 'nonce' => '验证失败,请刷新重试。',1409 1408 'code' => '验证码错误。', 1410 1409 'password' => '两次输入的密码不一致。' -
wpjam-basic/trunk/includes/class-wpjam-args.php
r3315366 r3320942 17 17 } 18 18 19 public function chain($value){20 return new WPJAM_Chainable($value, $this);21 }22 23 19 protected function call_dynamic_method($method, ...$args){ 24 $closure = is_closure($method) ? $method : self::dynamic_method('get', $method); 25 26 return $closure ? $this->bind_if_closure($closure)(...$args) : null; 20 return ($closure = self::dynamic_method('get', $method)) ? $this->bind_if_closure($closure)(...$args) : null; 27 21 } 28 22 … … 34 28 static $methods = []; 35 29 36 $called = self::get_called();37 $name = $called.':'.$method;38 39 30 if($action == 'add'){ 40 31 if(is_closure($args[0])){ 41 $methods[$ name] = $args[0];32 $methods[$method] = $args[0]; 42 33 } 43 34 }elseif($action == 'remove'){ 44 unset($methods[$ name]);35 unset($methods[$method]); 45 36 }elseif($action == 'get'){ 46 return $methods[$ name] ?? (($parent = get_parent_class($called)) ? $parent::dynamic_method('get', $method) : null);37 return $methods[$method] ?? (($parent = get_parent_class(get_called_class())) ? $parent::dynamic_method('get', $method) : null); 47 38 } 48 39 } … … 56 47 } 57 48 58 public static function get_called( $key=null){49 public static function get_called(){ 59 50 return strtolower(get_called_class()); 60 51 } … … 90 81 } 91 82 92 public function is_keyable($key){93 return is_int($key) || is_string($key) || is_null($key);94 }95 96 83 public function add_item($key, ...$args){ 97 if(!$args || !$this->is_keyable($key)){98 $ item = $key;84 if(!$args || is_bool($key) || (!is_scalar($key) && !is_null($key))){ 85 $args = [$key, ...$args]; 99 86 $key = null; 100 }else{ 101 $item = array_shift($args); 102 } 103 87 } 88 89 $item = array_shift($args); 104 90 $field = array_shift($args) ?: ''; 105 91 … … 290 276 291 277 protected function filter_args(){ 292 if(!$this->args && !is_array($this->args)){278 if(!$this->args){ 293 279 $this->args = []; 294 280 } … … 301 287 } 302 288 303 public function set_args($args){304 $this->args = $args;305 306 return $this;307 }308 309 289 public function update_args($args, $replace=true){ 310 290 $this->args = ($replace ? 'array_replace' : 'wp_parse_args')($this->get_args(), $args); … … 318 298 if(in_array($action, ['parse', 'callback'], true)){ 319 299 if(is_null($value)){ 320 if($this->model && $key && is_string($key) && !str_contains($key, '.')){ 321 $value = $this->parse_method('get_'.$key, 'model'); 322 } 300 $value = $this->model && $key && is_string($key) ? $this->parse_method('get_'.$key, 'model') : null; 323 301 }else{ 324 302 $value = $this->bind_if_closure($value); … … 427 405 428 406 public function call_method($method, ...$args){ 429 $called = $this->parse_method(...(is_array($method) ? $method : [$method]));430 431 if($called ){407 [$method, $type] = is_array($method) ? $method : [$method, '']; 408 409 if($called = $this->parse_method($method, $type)){ 432 410 return $called(...$args); 433 411 } 434 412 435 if( is_string($method) &&str_starts_with($method, 'filter_')){413 if(str_starts_with($method, 'filter_')){ 436 414 return array_shift($args); 437 415 } … … 501 479 502 480 protected function filter_args(){ 503 if(get_class($this) != self::class){ 504 $this->args = static::call_group('filter', $this->args); 481 if(get_class($this) != self::class && !in_array(($name = $this->args['name']), static::call_group('get_arg', 'filtered[]'))){ 482 static::call_group('update_arg', 'filtered[]', $name); 483 484 $this->args = apply_filters(static::call_group('get_arg', 'name').'_args', $this->args, $name); 505 485 } 506 486 … … 550 530 } 551 531 552 public static function get_group($args =[]){532 public static function get_group($args){ 553 533 return WPJAM_Register_Group::instance($args); 554 534 } 555 535 556 536 public static function call_group($method, ...$args){ 557 $called = get_called_class(); 558 559 if($called != self::class){ 537 if(($called = get_called_class()) != self::class){ 560 538 $group = static::get_group(['called'=>$called, 'name'=>strtolower($called)]); 561 539 … … 570 548 } 571 549 572 public static function re_register($name, $args, $merge=true){ 573 self::unregister($name); 574 575 return self::register($name, $args); 576 } 577 578 public static function unregister($name){ 579 static::call_group('remove_object', $name); 550 public static function unregister($name, $args=[]){ 551 static::call_group('remove_object', $name, $args); 580 552 } 581 553 … … 631 603 632 604 public function get_object($name, $by='', $top=''){ 633 if($by == 'model'){ 634 if($name && strcasecmp($name, $top) !== 0){ 635 return array_find($this->get_objects(), fn($v)=> $v->model && is_string($v->model) && strcasecmp($name, $v->model) === 0) ?: $this->get_object(get_parent_class($name), $by, $top); 636 } 637 }elseif($name){ 638 return $this->get_arg('objects['.$name.']') ?: $this->by_default($name); 639 } 605 if($name){ 606 if(!$by){ 607 return $this->get_arg('objects['.$name.']') ?: $this->by_default($name); 608 } 609 610 if($by == 'model' && strcasecmp($name, $top) !== 0){ 611 return array_find($this->get_objects(), fn($v)=> is_string($v->model) && strcasecmp($name, $v->model) === 0) ?: $this->get_object(get_parent_class($name), $by, $top); 612 } 613 } 640 614 } 641 615 … … 703 677 } 704 678 705 public function filter($args){706 $name = $args['name'];707 708 return in_array($name, $this->get_arg('filtered[]')) ? $args : apply_filters($this->update_arg('filtered[]', $name)->name.'_args', $args, $name);709 }710 711 679 public function get_active($key=null){ 712 $objects = array_filter($this->get_objects(), fn($object)=> $object->active ?? $object->is_active()); 713 714 return $key ? array_filter(array_map(fn($object)=> $object->get_arg($key), $objects), fn($v)=> !is_null($v)) : $objects; 680 return wpjam_array($this->get_objects(), fn($k, $v)=> ($v->active ?? $v->is_active()) ? [$k, $key ? $v->get_arg($key) : $v] : null, true); 715 681 } 716 682 … … 718 684 $type = array_find(['filter', 'get'], fn($type)=> str_starts_with($method, $type.'_')); 719 685 720 foreach($this->get_active() as $object){721 $result = $object->call_method($method, ...$args); // 不能调用对象本身的方法,会死循环722 723 if(is_wp_error($result)){ 724 return $result;725 }726 727 if($type == 'filter'){728 $args[0] = $result;729 }elseif($type == 'get'){730 if($result && is_array($result)){731 $return = array_merge(($return ?? []), $result);732 }733 }734 } 686 try{ 687 foreach($this->get_active() as $object){ 688 $result = $object->try('call_method', $method, ...$args); 689 690 if($type == 'filter'){ 691 $args[0] = $result; 692 }elseif($type == 'get'){ 693 if($result && is_array($result)){ 694 $return = array_merge(($return ?? []), $result); 695 } 696 } 697 } 698 }catch(Exception $e){ 699 return wpjam_catch($e); 700 } 735 701 736 702 if($type == 'filter'){ … … 805 771 if($this->admin){ 806 772 $data = wpjam_if_error(wpjam_fields($this->fields)->catch('get_parameter', 'POST'), 'send'); 773 $verify = wpjam_get($data, 'action_type') !== 'form'; 807 774 }else{ 808 775 $data = array_merge(wpjam_get_data_parameter(), wpjam_except(wpjam_get_post_parameter(), ['action', 'defaults', 'data', '_ajax_nonce'])); 809 776 $data = array_merge($data, wpjam_if_error(wpjam_fields($this->fields)->catch('validate', $data, 'parameter'), 'send')); 810 $action = $this->parse_nonce_action($this->name, $data); 811 812 if($action && !check_ajax_referer($action, false, false)){ 813 wp_die('invalid_nonce'); 814 } 815 } 816 777 $verify = $this->verify !== false; 778 } 779 780 $action = $verify ? $this->parse_nonce_action($this->name, $data) : ''; 781 782 if($action && !check_ajax_referer($action, false, false)){ 783 wpjam_send_json(['errcode'=>'invalid_nonce', 'errmsg'=>'验证失败,请刷新重试。']); 784 } 785 786 if($this->allow && !wpjam_call($this->allow, $data)){ 787 wp_die('access_denied'); 788 } 789 817 790 return wpjam_send_json(wpjam_catch($this->callback, $data, $this->name)); 818 791 } 819 792 820 public static function parse_nonce_action($name, $data){ 821 $args = self::get($name); 822 823 return wpjam_get($args, 'verify') === false ? '' : array_reduce(wpjam_get($args, 'nonce_keys') ?: [], fn($carry, $k)=> !empty($data[$k]) ? $carry.':'.$data[$k] : $carry, $name); 793 public static function parse_nonce_action($name, $data=[]){ 794 return ($nonce = wpjam('ajax', $name.'[nonce_action]')) ? $nonce($data) : (wpjam('ajax', $name.'[admin]') ? '' : $name.implode(':', array_filter(wpjam_fill(wpjam('ajax', $name.'[nonce_keys]') ?: [], fn($k)=> $data[$k] ?? '')))); 795 } 796 797 public static function parse_submit_button($button, $submit=null){ 798 $cb = fn($item)=> (is_array($item) ? $item : ['text'=>$item])+['class'=>'primary']; 799 800 if($submit){ 801 return isset($button[$submit]) ? $cb($button[$submit]) : wp_die('无效的提交按钮'); 802 } 803 804 foreach(array_filter($button) as $key => $item){ 805 $item = $cb($item); 806 $parsed[] = get_submit_button($item['text'], $item['class'], $key, false); 807 } 808 809 return isset($parsed) ? wpjam_tag('p', ['submit'], implode($parsed)) : wpjam_tag(); 810 } 811 812 public static function get_attr($name, $data=[]){ 813 if(wpjam('ajax', $name)){ 814 return ['action'=>$name, 'data'=>$data]+(($action = self::parse_nonce_action($name, $data)) ? ['nonce'=>wp_create_nonce($action)] : []); 815 } 824 816 } 825 817 … … 840 832 } 841 833 842 if(wp_doing_ajax() && wpjam_get($_REQUEST, 'action') == $name){ 843 $prefix = 'wp_ajax_'; 844 845 if(!is_user_logged_in()){ 846 if(!wpjam_pull($args, 'nopriv')){ 847 return; 848 } 849 850 $prefix .= 'nopriv_'; 851 } 852 853 add_action($prefix.$name, [new static(['name'=>$name]+$args), 'callback']); 834 if(wp_doing_ajax() && wpjam_get($_REQUEST, 'action') == $name && (is_user_logged_in() || !empty($args['nopriv']))){ 835 add_action('wp_ajax_'.(is_user_logged_in() ? '' : 'nopriv_').$name, [new static(['name'=>$name]+$args), 'callback']); 854 836 } 855 837 856 838 return wpjam('ajax', $name, $args); 857 }858 859 public static function get($name){860 return wpjam('ajax', $name);861 839 } 862 840 } … … 969 947 foreach($items as $i => &$item){ 970 948 if($args['calc']){ 971 if(is_array($args['calc']) && !empty($args['key']) && isset($args['calc'][$item[$args['key']]])){ 972 $item = array_merge($item, $args['calc'][$item[$args['key']]]); 973 }else{ 974 $item = $this->calc($item); 975 } 949 $item = $this->calc($item); 976 950 } 977 951 … … 998 972 if($args['sum']){ 999 973 $sums = $this->calc($sums, ['sum'=>true])+(is_array($args['sum']) ? $args['sum'] : []); 1000 $sums = $args['format'] ? $this->format($sums) : $sums; 1001 $items = wpjam_add_at($items, 0, '__sum', $sums); 974 $items = wpjam_add_at($items, 0, '__sum__', ($args['format'] ? $this->format($sums) : $sums)); 975 976 unset($sums); 1002 977 } 1003 978 … … 1093 1068 1094 1069 public function sum($items, $args=[]){ 1095 if($this->sumable && $items){ 1096 if($field = wpjam_pull($args, 'field')){ 1097 return wpjam_map(wpjam_group($items, $field), fn($items, $field)=> array_merge(array_values($items)[0], $this->sum($items, $args))); 1098 }else{ 1099 return $this->calc(wpjam_at($this->process($items, $args+['sum'=>true]), 0), ['sum'=>true]); 1100 } 1101 } 1102 1103 return []; 1104 } 1105 1106 public function accumulate($results, $items, $args=[]){ 1107 $field = wpjam_pull($args, 'field'); 1108 $calc = wpjam_pull($args, 'calc'); 1109 $items = wp_is_numeric_array($items ) ? $items : [$items]; 1070 return ($this->sumable && $items) ? $this->calc(wpjam_at($this->process($items, $args+['sum'=>true]), 0), ['sum'=>true]) : []; 1071 } 1072 1073 public function accumulate($to, $items, $args=[]){ 1074 $args = wp_parse_args($args, ['calc'=>true, 'field'=>'', 'filter'=>'']); 1075 $keys = array_keys(array_filter($this->sumable ?: [], fn($v)=> $v == 1)); 1076 1077 if(!$args['field']){ 1078 $group = '____'; 1079 $to = [$group=>($to ?: array_fill_keys($keys, 0))]; 1080 } 1110 1081 1111 1082 foreach($items as $item){ 1112 $item = $calc ? $this->calc($item) : $item; 1113 $value = $field ? ($item[$field] ?? '') : '__'; 1114 $keys = $this->sumable ? array_keys(array_filter($this->sumable, fn($v)=> $v == 1)) : []; 1115 1116 $results[$value] ??= array_merge($item, array_fill_keys($keys, 0)); 1083 if($args['calc']){ 1084 $item = $this->calc($item); 1085 } 1086 1087 if($args['filter'] && !wpjam_match($item, $args['filter'], 'AND')){ 1088 continue; 1089 } 1090 1091 if($args['field']){ 1092 $group = $item[$args['field']] ?? ''; 1093 } 1094 1095 $exists = isset($to[$group]); 1096 1097 if(!$exists){ 1098 $to[$group] = $item; 1099 } 1117 1100 1118 1101 foreach($keys as $k){ 1119 if($r = isset($item[$k]) ? $this->parse_number($item[$k]) : 0){ 1120 $results[$value][$k] += $r; 1121 } 1122 } 1123 } 1124 1125 return $field ? $results : $results[$value]; 1102 $to[$group][$k] = ($exists ? $to[$group][$k] : 0)+($this->parse_number($item[$k] ?? 0) ?: 0); 1103 } 1104 } 1105 1106 return $args['field'] ? $to : $to[$group]; 1126 1107 } 1127 1108 … … 1407 1388 } 1408 1389 } 1409 1410 class WPJAM_Chainable{1411 private $value;1412 private $object;1413 1414 public function __construct($value, $object){1415 $this->value = $value;1416 $this->object = $object;1417 }1418 1419 public function __call($method, $args){1420 if($method == 'value'){1421 if(!$args){1422 return $this->value;1423 }1424 1425 $this->value = $args[0];1426 }else{1427 $this->value = wpjam_try([$this->object, $method], $this->value, ...$args);1428 }1429 1430 return $this;1431 }1432 } -
wpjam-basic/trunk/includes/class-wpjam-field.php
r3315366 r3320942 470 470 } 471 471 472 $schema += wpjam_array($map ?? [], fn($k, $v)=> isset($this->$v) ? [$k, $this->$v] : null);472 $schema += wpjam_array($map ?? [], fn($k, $v)=> [$k, $this->$v], true); 473 473 $rest = $this->show_in_rest; 474 474 … … 1100 1100 $type = 'hidden'; 1101 1101 $size = wpjam_parse_size($this->size ?: '600x0', [600, 600]); 1102 $data = ['thumb_args'=> wpjam_get_thumbnail_args($size), 'size'=> array_filter(wpjam_map($size, fn($v)=> (int)($v/2)))];1102 $data = ['thumb_args'=> wpjam_get_thumbnail_args($size), 'size'=>wpjam_array($size, fn($k, $v)=> [$k, (int)($v/2) ?: null], true)]; 1103 1103 } 1104 1104 … … 1152 1152 return new WPJAM_Field($field); 1153 1153 } 1154 1155 public static function ajax_upload($data){1156 if(!check_ajax_referer('upload-'.$data['name'], false, false)){1157 wp_die('invalid_nonce');1158 }1159 1160 return wpjam_upload($data['name'], ['mimes'=>$data['mimes']]);1161 }1162 1154 } 1163 1155 -
wpjam-basic/trunk/includes/class-wpjam-list-table.php
r3315366 r3320942 20 20 $this->_args = $args; 21 21 $this->screen = $screen = get_current_screen(); 22 23 $args = compact('screen');24 $style = [$this->style];25 22 26 23 foreach($this->get_objects('action') as $object){ … … 55 52 56 53 if($this->layout == 'calendar'){ 57 $this->query_args = ['year', 'month', ... wpjam_array($this->query_args)];54 $this->query_args = ['year', 'month', ...(array)$this->query_args]; 58 55 }else{ 59 56 if(!$this->builtin && !empty($args['bulk_actions'])){ … … 62 59 63 60 foreach($this->get_objects('column') as $object){ 64 $style[]= $object->style;65 61 $key = $object->name; 66 62 $data = array_filter(wpjam_pick($object, ['description', 'sticky', 'nowrap', 'format', 'precision', 'conditional_styles'])); … … 71 67 $args['sortable_columns'][$key] = [$key, true]; 72 68 } 73 } 74 } 75 76 wpjam_admin('style', array_filter($style)); 69 70 wpjam_admin('style', $object->style); 71 } 72 } 73 74 wpjam_admin('style', $this->style); 77 75 wpjam_admin('vars[list_table]', fn()=> $this->get_setting()); 78 76 wpjam_admin('vars[page_title_action]', fn()=> $this->get_action('add', ['class'=>'page-title-action']) ?: ''); … … 82 80 add_filter('manage_'.$screen->id.'_sortable_columns', [$this, 'filter_sortable_columns']); 83 81 84 $this->_args = array_merge($this->_args, $args );82 $this->_args = array_merge($this->_args, $args+['screen'=>$screen]); 85 83 86 84 if($this->builtin){ … … 124 122 $this->filterable = array_merge($value, array_keys($fields)); 125 123 126 $fields = wpjam_map($fields, fn($field)=> [(wpjam_get($field, 'type') === 'select' || wpjam_get($field, '_type') === 'mu-select' ? 'show_option_all' : 'placeholder') => wpjam_pull($field, 'title')]+wpjam_except($field, ['before', 'after', 'required', 'show_admin_column']));124 $fields = array_map(fn($field)=> [(wpjam_get($field, 'type') === 'select' || wpjam_get($field, '_type') === 'mu-select' ? 'show_option_all' : 'placeholder') => wpjam_pull($field, 'title')]+wpjam_except($field, ['before', 'after', 'required', 'show_admin_column']), $fields); 127 125 128 126 return $this->$name = $fields+(($fields && !$this->builtin && $this->sortable_columns) ? [ … … 267 265 268 266 protected function get_actions($names, $args=[]){ 269 return array_filter(array_map(fn($n)=> $this->get_action($n, $args), $names ?: []));267 return wpjam_array($names ?: [], fn($i, $n)=> [$i, $this->get_action($n, $args)], true); 270 268 } 271 269 … … 303 301 $attr = $id ? ['id'=>$this->singular.'-'.str_replace('.', '-', $id), 'data'=>['id'=>$id]] : []; 304 302 305 $item['row_actions'] = $id ? $this->filter_row_actions([], $item) : ['error'=>'Primary Key「'.$this->primary_key.'」不存在'];303 $item['row_actions'] = $id ? $this->filter_row_actions([], $item) : ($this->row_actions ? ['error'=>'Primary Key「'.$this->primary_key.'」不存在'] : []); 306 304 307 305 $this->before_single_row_by_model($raw); … … 521 519 522 520 if(wp_doing_ajax()){ 523 return wpjam_add_admin_ajax('wpjam-list-table-action', [$this, 'ajax_response']); 521 return wpjam_add_admin_ajax('wpjam-list-table-action', [ 522 'callback' => [$this, 'ajax_response'], 523 'nonce_action' => fn($data)=> ($object = $this->get_object($data['list_action'] ?? '')) ? $object->parse_nonce_action($data) : null 524 ]); 524 525 } 525 526 … … 616 617 617 618 protected function get_table_classes(){ 618 $classes = [...parent::get_table_classes(), ($this->nowrap ? 'nowrap' : '')]; 619 $removed = [($this->fixed ? '' : 'fixed'), ($this->layout == 'calendar' ? 'striped' : '')]; 620 621 return array_diff($classes, $removed); 619 return array_merge(array_diff(parent::get_table_classes(), ($this->fixed ? [] : ['fixed']), ($this->layout == 'calendar' ? ['striped'] : [])), $this->nowrap ? ['nowrap'] : []); 622 620 } 623 621 … … 738 736 } 739 737 740 public function create_nonce($args=[]){741 return wp_create_nonce($this->parse_nonce_action($args));742 }743 744 public function verify_nonce($args=[]){745 return check_ajax_referer($this->parse_nonce_action($args), false, false);746 }747 748 738 public function callback($args){ 749 739 if(is_array($args)){ … … 858 848 || ($this->bulk === 'export' && $args['bulk']) 859 849 )){ 860 $args += ['export_action'=>$this->name, '_wpnonce'=> $this->create_nonce($args)];850 $args += ['export_action'=>$this->name, '_wpnonce'=>wp_create_nonce($this->parse_nonce_action($args))]; 861 851 $args += $submit_name != $this->name ? ['submit_name'=>$submit_name] : []; 862 852 … … 870 860 if($type == 'form'){ 871 861 return $response+['form'=>$this->get_form($form_args, $type)]; 872 }873 874 if(!$this->verify_nonce($args)){875 wp_die('invalid_nonce');876 862 } 877 863 … … 992 978 $fields = $object->get_fields($args, false, $type)->render(); 993 979 $args = ($prev && $id && $type == 'form') ? wpjam_merge($args, ['data'=>$prev->get_data($id, true)]) : $args; 994 $button = ($prev ? $prev->render(['class'=>['button'], 'title'=>'上一步']+$args) : '').$object->get_submit_button($args); 995 $form = $fields->wrap('form', ['novalidate', 'id'=>'list_table_action_form', 'data'=>$object->generate_data_attr($args, 'form')]); 996 997 return $button ? $form->append('p', ['submit'], $button) : $form; 980 $button = $object->get_submit_button($args)->prepend($prev ? $prev->render(['class'=>['button'], 'title'=>'上一步']+$args) : ''); 981 982 return $fields->after($button)->wrap('form', ['novalidate', 'id'=>'list_table_action_form', 'data'=>$object->generate_data_attr($args, 'form')]); 998 983 } 999 984 … … 1044 1029 $button = is_array($button) ? $button : [$this->name => $button]; 1045 1030 1046 return wpjam_parse_submit_button($button, $name);1031 return WPJAM_AJAX::parse_submit_button($button, $name); 1047 1032 } 1048 1033 … … 1123 1108 public function generate_data_attr($args=[], $type='button'){ 1124 1109 $data = wp_parse_args(($args['data'] ?? []), ($this->data ?: []))+($this->layout == 'calendar' ? wpjam_pick($args, ['date']) : []); 1125 $attr = ['data'=>$data, 'action'=>$this->name, 'nonce'=> $this->create_nonce($args)];1110 $attr = ['data'=>$data, 'action'=>$this->name, 'nonce'=>wp_create_nonce($this->parse_nonce_action($args))]; 1126 1111 $attr += $this->overall ? [] : ($args['bulk'] ? wpjam_pick($args, ['ids'])+wpjam_pick($this, ['bulk', 'title']) : wpjam_pick($args, ['id'])); 1127 1112 -
wpjam-basic/trunk/includes/class-wpjam-model.php
r3310594 r3320942 396 396 397 397 foreach(['group_cache_key', 'lazyload_key', 'filterable_fields', 'searchable_fields'] as $key){ 398 $this->$key = wpjam_array($this->$key);398 $this->$key = (array)$this->$key; 399 399 } 400 400 … … 744 744 if($orderby){ 745 745 if(is_array($orderby)){ 746 $parsed = array_filter(wpjam_map($orderby, fn($v, $k)=> $this->parse_orderby($k, $v))); 747 $orderby = $parsed ? implode(', ', $parsed) : ''; 746 $orderby = implode(', ', wpjam_array($orderby, fn($k, $v)=> [$k, $this->parse_orderby($k, $v)], true)); 748 747 }elseif(str_contains($orderby, ',') || (str_contains($orderby, '(') && str_contains($orderby, ')'))){ 749 748 $orderby = $orderby; … … 819 818 return sprintf('RAND(%s)', (int)$matches[1]); 820 819 }elseif(str_ends_with($orderby, '__in')){ 821 return '';820 return null; 822 821 // $field = str_replace('__in', '', $orderby); 823 822 } … … 846 845 847 846 if($orderby == 'meta_value_num' || $orderby == 'meta_value'){ 848 return '';847 return null; 849 848 } 850 849 … … 1373 1372 1374 1373 if($this->item_type == 'array'){ 1375 $this->lazyload_key = wpjam_array($this->lazyload_key);1374 $this->lazyload_key = (array)$this->lazyload_key; 1376 1375 $this->primary_key ??= 'id'; 1377 1376 }else{ -
wpjam-basic/trunk/includes/class-wpjam-post.php
r3315366 r3320942 475 475 476 476 protected static function sanitize_data($data, $post_id=0){ 477 $data += wpjam_array(get_class_vars('WP_Post'), fn($k, $v)=> try_remove_prefix($k, 'post_') && isset($data[$k]) ? ['post_'.$k, $data[$k]] : null);477 $data += wpjam_array(get_class_vars('WP_Post'), fn($k, $v)=> try_remove_prefix($k, 'post_') ? ['post_'.$k, $data[$k] ?? null] : null, true); 478 478 479 479 if(isset($data['post_content']) && is_array($data['post_content'])){ … … 680 680 681 681 if($key == 'model'){ 682 if(!$value || !class_exists($value) || !is_subclass_of($value, 'WPJAM_Post')){682 if(!$value || !class_exists($value)){ 683 683 return 'WPJAM_Post'; 684 684 } … … 1509 1509 $clauses['join'] .= "LEFT JOIN {$wpdb->postmeta} jam_pm ON {$wpdb->posts}.ID = jam_pm.post_id AND jam_pm.meta_key = '{$meta_key}' "; 1510 1510 $clauses['orderby'] = "(COALESCE(jam_pm.meta_value, 0)+0) {$order}, " . $clauses['orderby']; 1511 $clauses['groupby'] = "{$wpdb->posts}.ID"; 1511 1512 }elseif(in_array($orderby, ['', 'date', 'post_date'])){ 1512 1513 $clauses['orderby'] .= ", {$wpdb->posts}.ID {$order}"; -
wpjam-basic/trunk/includes/class-wpjam-setting.php
r3310594 r3320942 306 306 public function page_load(){ 307 307 if(wp_doing_ajax()){ 308 wpjam_add_admin_ajax('wpjam-option-action', [$this, 'ajax_response']); 308 wpjam_add_admin_ajax('wpjam-option-action', [ 309 'callback' => [$this, 'ajax_response'], 310 'nonce_action' => fn()=> $this->option_group, 311 'allow' => fn()=> current_user_can($this->capability) 312 ]); 309 313 } 310 314 } 311 315 312 316 public function ajax_response(){ 313 if(!check_ajax_referer($this->option_group, false, false)){314 wp_die('invalid_nonce');315 }316 317 if(!current_user_can($this->capability)){318 wp_die('access_denied');319 }320 321 317 flush_rewrite_rules(); 322 318 … … 374 370 ]; 375 371 376 $sub = self::generate_sub_name($args); 377 $rest = $sub ? wpjam_except($args, ['model', 'menu_page', 'admin_load', 'plugin_page', 'current_tab']) : []; 378 $object = self::get($name); 379 380 if($object){ 381 if($sub){ 382 return $object->update_args(wpjam_except($rest, 'title'))->register_sub($sub, $args); 383 } 384 385 if(is_null($object->primary)){ 386 return self::re_register($name, array_merge($object->to_array(), $args, ['primary'=>true])); 387 } 388 389 trigger_error('option_setting'.'「'.$name.'」已经注册。'.var_export($args, true)); 390 391 return $object; 372 if($sub = self::generate_sub_name($args)){ 373 $rest = wpjam_except($args, ['model', 'menu_page', 'admin_load', 'plugin_page', 'current_tab']); 374 }else{ 375 $args = ['primary'=>true]+$args; 376 } 377 378 if($object = self::get($name)){ 379 if($sub || is_null($object->primary)){ 380 $object->update_args($sub ? wpjam_except($rest, 'title') : $args); 381 }else{ 382 trigger_error('option_setting'.'「'.$name.'」已经注册。'.var_export($args, true)); 383 } 392 384 }else{ 393 385 if($args['option_type'] == 'array' && !doing_filter('sanitize_option_'.$name) && is_null(get_option($name, null))){ … … 395 387 } 396 388 397 if($sub){ 398 return (self::register($name, $rest))->register_sub($sub, $args); 399 } 400 401 return self::register($name, array_merge($args, ['primary'=>true])); 402 } 389 $object = self::register($name, $sub ? $rest : $args); 390 } 391 392 return $sub ? $object->register_sub($sub, $args) : $object; 403 393 } 404 394 } … … 406 396 class WPJAM_Option_Model{ 407 397 protected static function call_method($method, ...$args){ 408 $object = self::get_object(); 409 410 return $object ? $object->$method(...$args) : null; 398 return ($object = self::get_object()) ? $object->$method(...$args) : null; 411 399 } 412 400 … … 514 502 515 503 public function sanitize_callback($data){ 516 return wpjam_array( array_filter($data), fn($k)=> $this->handle($k, 'parse'));504 return wpjam_array($data, fn($k, $v)=> $v ? $this->handle($k, 'parse') : null); 517 505 } 518 506 -
wpjam-basic/trunk/includes/class-wpjam-term.php
r3315366 r3320942 491 491 492 492 if($key == 'model'){ 493 if(!$value || !class_exists($value) || !is_subclass_of($value, 'WPJAM_Term')){493 if(!$value || !class_exists($value)){ 494 494 return 'WPJAM_Term'; 495 495 } … … 965 965 } 966 966 967 $mapping = wpjam_pull($args, 'mapping'); 968 $mapping = $mapping ? array_filter(array_map('wpjam_get_parameter', wp_parse_args($mapping)), fn($v)=> isset($v)) : []; 967 $mapping = wpjam_array(wp_parse_args(wpjam_pull($args, 'mapping') ?: []), fn($k, $v)=> [$k, wpjam_get_parameter($v)], true); 969 968 $args = array_merge($args, $mapping); 970 969 $number = (int)wpjam_pull($args, 'number'); -
wpjam-basic/trunk/includes/class-wpjam-user.php
r3305886 r3320942 771 771 'title' => '绑定账号', 772 772 'order' => 20, 773 'callback' => fn($user_id)=> implode('<br /><br />', array_filter(wpjam_map($objects, fn($object)=> ($openid = $object->get_openid($user_id)) ? $object->title.':<br />'.$openid : '')))773 'callback' => fn($user_id)=> implode('<br /><br />', wpjam_array($objects, fn($object)=> ($openid = $object->get_openid($user_id)) ? $object->title.':<br />'.$openid : null), true) 774 774 ]) 775 775 ]); -
wpjam-basic/trunk/public/wpjam-compat.php
r3315366 r3320942 181 181 function wpjam_remove_postfix($str, $postfix, &$removed=false){ 182 182 return wpjam_remove_suffix($str, $postfix, $removed); 183 } 184 185 function wpjam_get_plain_text($text){ 186 return $text ? trim(preg_replace('/\s+/', ' ', str_replace(['"', '\'', "\r\n", "\n"], ['', '', ' ', ' '], wp_strip_all_tags($text)))) : $text; 183 187 } 184 188 -
wpjam-basic/trunk/public/wpjam-functions.php
r3315366 r3320942 395 395 $posts = WPJAM_Post::get_by_ids($ids); 396 396 397 return $parse ? array_values(array_filter(array_map(fn($p)=> wpjam_get_post($p, $args), $ids))) : $posts;397 return $parse ? wpjam_array($ids, fn($i, $p)=> [null, wpjam_get_post($p, $args)], true) : $posts; 398 398 } 399 399 … … 864 864 865 865 function wpjam_get_ajax_data_attr($name, $data=[], $output=null){ 866 if(WPJAM_AJAX::get($name)){ 867 $action = WPJAM_AJAX::parse_nonce_action($name, $data); 868 $attr = ['action'=>$name, 'data'=>$data, 'nonce'=>($action ? wp_create_nonce($action) : null)]; 869 870 return $output ? $attr : wpjam_attr($attr, 'data'); 871 } 872 873 return $output ? null : []; 866 $attr = WPJAM_AJAX::get_attr($name, $data); 867 868 return $output ? ($attr ?: []) : ($attr ? wpjam_attr($attr, 'data') : null); 874 869 } 875 870 -
wpjam-basic/trunk/public/wpjam-route.php
r3315366 r3320942 239 239 if(count($args) > 1 || ($args && (is_string($args[0]) || is_bool($args[0])))){ 240 240 $group = array_shift($args); 241 $cb = array_shift($args); 242 $arg = array_shift($args); 241 243 $fix = is_bool($group) ? ($group ? 'site_' : '').'transient' : ''; 242 244 $group = $fix ? '' : ($group ?: 'default'); 243 $ cb = array_shift($args);244 $expire = array_shift($args) ?: 86400;245 $args = is_numeric($arg) ? ['expire'=>$arg] : (array)$arg; 246 $expire = wpjam_get($args, 'expire') ?: 86400; 245 247 246 248 if($expire === -1){ 247 249 return $fix ? ('delete_'.$fix)($key) : wp_cache_delete($key, $group); 248 250 } 249 250 $force = array_shift($args);251 252 $force = wpjam_get($args, 'force'); 251 253 $value = $fix ? ('get_'.$fix)($key) : wp_cache_get($key, $group, ($force === 'get' || $force === true)); 252 254 253 if($cb && ($value === false || ($force === 'set' || $force === true))){255 if($cb && ($value === false || $force === 'set' || $force === true)){ 254 256 $value = $cb($value, $key, $group); 255 257 … … 269 271 } 270 272 271 function wpjam_transient($name, $callback, $ expire=86400, $global=false, $force=false){272 return wpjam_cache($name, (bool)$global, $callback, $ expire, $force);273 function wpjam_transient($name, $callback, $args=[], $global=false){ 274 return wpjam_cache($name, (bool)$global, $callback, $args); 273 275 } 274 276 275 277 function wpjam_increment($name, $max=0, $expire=86400, $global=false){ 276 $cb = fn($v)=> ($max && (int)$v >= $max ? 0 : (int)$v)+1; 277 278 return wpjam_transient($name, $cb, $expire, $global, 'set')-1; 278 return wpjam_transient($name, fn($v)=> ($max && (int)$v >= $max) ? 1 : (int)$v+1, ['expire'=>$expire, 'force'=>'set'], $global); 279 279 } 280 280 281 281 function wpjam_lock($name, $expire=10, $group=false){ 282 $group = is_bool($group) ? ($group ? 'site-' : '').'transient' : $group; 283 $locked = true; 284 $result = wpjam_cache($name, $group, function($v) use(&$locked){ 285 $locked = $v; 286 return 1; 287 }, $expire, 'get'); 288 289 return $expire == -1 ? $result : $locked; 282 $group = is_bool($group) ? ($group ? 'site-' : '').'transient' : ($group ?: 'default'); 283 284 return $expire == -1 ? wp_cache_delete($name, $group) : (wp_cache_get($name, $group, true) || !wp_cache_add($name, 1, $group, $expire)); 290 285 } 291 286 292 287 function wpjam_is_over($name, $max, $time, $group=false, $action='increment'){ 293 $times = wpjam_cache($name, $group) ?: 0; 294 $result = $times > $max; 295 296 if(!$result && $action == 'increment'){ 297 wpjam_cache($name, $group, fn()=> $times+1, ($max == $times && $time > 60) ? $time : 60, 'set'); 298 } 299 300 return $result; 288 $times = wp_cache_get($name, $group) ?: 0; 289 290 return ($times > $max) || ($action == 'increment' && wp_cache_set($name, $times+1, $group, ($max == $times && $time > 60) ? $time : 60) && false); 301 291 } 302 292 … … 659 649 660 650 function wpjam_add_admin_ajax($action, $args=[]){ 661 wpjam_register_ajax($action, ['admin'=>true]+ (wpjam_is_assoc_array($args) ? $args : ['callback'=>$args]));651 wpjam_register_ajax($action, ['admin'=>true]+$args); 662 652 } 663 653 … … 685 675 wpjam_admin($type.'_load[]', $args); 686 676 } 687 }688 689 function wpjam_parse_submit_button($button, $name=null){690 foreach(array_filter($button) as $key => $item){691 if(!$name || $name == $key){692 $item = (is_array($item) ? $item : ['text'=>$item])+['class'=>'primary'];693 694 if($name){695 return $item;696 }697 698 $parsed[] = get_submit_button($item['text'], $item['class'], $key, false);699 }700 }701 702 return $name ? wp_die('无效的提交按钮') : implode('', $parsed ?? []);703 677 } 704 678 -
wpjam-basic/trunk/public/wpjam-utils.php
r3315366 r3320942 369 369 370 370 if(isset($map)){ 371 $data[] = array_map(fn($i)=> preg_replace('/="([^"]*)"/', '$1', $row[$i]), $map);371 $data[] = array_map(fn($i)=> preg_replace('/="([^"]*)"/', '$1', $row[$i]), $map); 372 372 }else{ 373 $row = array_map(fn($v)=> trim(trim($v), "\xEF\xBB\xBF"), $row); 374 $columns = array_flip(array_map('trim', $columns)); 375 $map = wpjam_array($row, fn($k, $v)=> isset($columns[$v]) ? [$columns[$v], $k] : (in_array($v, $columns) ? [$v, $k] : null)); 373 if($columns){ 374 $row = array_map(fn($v)=> trim(trim($v), "\xEF\xBB\xBF"), $row); 375 $columns= array_flip(array_map('trim', $columns)); 376 $map = wpjam_array($row, fn($k, $v)=> isset($columns[$v]) ? [$columns[$v], $k] : (in_array($v, $columns) ? [$v, $k] : null)); 377 }else{ 378 $map = array_flip(array_map(fn($v)=> trim(trim($v), "\xEF\xBB\xBF"), $row)); 379 } 376 380 } 377 381 } … … 545 549 } 546 550 547 function wpjam_array($arr=null, $callback=null ){551 function wpjam_array($arr=null, $callback=null, $skip_null=false){ 548 552 if(is_object($arr)){ 549 553 if(method_exists($arr, 'to_array')){ … … 561 565 } 562 566 563 if($ callback && is_callable($callback)){567 if($data && $callback && is_callable($callback)){ 564 568 foreach($data as $k => $v){ 565 569 $result = $callback($k, $v); 566 570 567 if(!is_null($result)){ 568 [$k, $v] = is_array($result) ? $result : [$result, $v]; 569 570 if(is_null($k)){ 571 $new[] = $v; 572 }else{ 573 $new[$k] = $v; 571 if(is_array($result)){ 572 if(count($result) != 2){ 573 continue; 574 574 } 575 576 [$k, $v] = $result; 577 578 if($skip_null && is_null($v)){ 579 continue; 580 } 581 }elseif(is_scalar($result)){ 582 $k = $result; 583 }else{ 584 continue; // null、对象等非标量均跳过 585 } 586 587 if(is_null($k)){ 588 $new[] = $v; 589 }else{ 590 $new[$k] = $v; 575 591 } 576 592 } … … 793 809 794 810 if(wpjam_is_assoc_array($args[0])){ 795 $args = wpjam_reduce($args[0], fn($carry, $v, $k)=>[...$carry, ($column = array_column($arr, $k)), $is_asc($v) ? SORT_ASC : SORT_DESC, is_numeric(current($column)) ? SORT_NUMERIC : SORT_REGULAR], []); 811 $args = wpjam_reduce($args[0], fn($carry, $order, $field)=>[ 812 ...$carry, 813 ($column = array_column($arr, $field)), 814 $is_asc($order) ? SORT_ASC : SORT_DESC, 815 is_numeric(current($column)) ? SORT_NUMERIC : SORT_REGULAR 816 ], []); 796 817 }elseif(is_callable($args[0]) || is_string($args[0])){ 818 $field = $args[0]; 797 819 $order = $args[1] ?? ''; 798 820 799 if(is_callable($ args[0])){800 $column = array_map($ args[0], ($order === 'key' ? array_keys($arr) : $arr));821 if(is_callable($field)){ 822 $column = array_map($field, ($order === 'key' ? array_keys($arr) : $arr)); 801 823 $flag = $args[2] ?? SORT_NUMERIC; 802 824 }else{ 803 $k = $args[0]; 804 $d = $args[2] ?? 0; 805 806 $column = array_map(fn($v)=> wpjam_get($v, $k, $d), $arr); 807 $flag = is_numeric($d) ? SORT_NUMERIC : SORT_REGULAR; 825 $default= $args[2] ?? 0; 826 $column = array_map(fn($item)=> wpjam_get($item, $field, $default), $arr); 827 $flag = is_numeric($default) ? SORT_NUMERIC : SORT_REGULAR; 808 828 } 809 829 … … 934 954 } 935 955 936 if(str_ends_with($key, '[]')){ 956 if($key === '[]'){ 957 $arr[] = $value; 958 959 return $arr; 960 }elseif(str_ends_with($key, '[]')){ 937 961 $current = wpjam_get($arr, $key); 938 962 $current[] = $value; … … 1170 1194 } 1171 1195 1172 //获取纯文本1173 function wpjam_get_plain_text($text){1174 return $text ? trim(preg_replace('/\s+/', ' ', str_replace(['"', '\'', "\r\n", "\n"], ['', '', ' ', ' '], wp_strip_all_tags($text)))) : $text;1175 }1176 1177 1196 //获取第一段 1178 1197 function wpjam_get_first_p($text){ -
wpjam-basic/trunk/readme.txt
r3305886 r3320942 54 54 == Changelog == 55 55 56 = 6.8.1 = 57 * wpjam_set 支持 [] 模式新增元素 58 * 全面优化 WPJAM_AJAX class,整合后台的 AJAX 操作 59 * 优化 wpjam_sort 排序函数 60 * 其他优化和bug修复 61 56 62 = 6.8 = 57 63 * 全面优化 wpjam_try / wpjam_catch 等高阶函数 … … 69 75 * 新增函数 wpjam_reduce 70 76 * 新增函数 wpjam_bettwen 71 * 其他优化和bug修复72 77 73 78 = 6.6 = -
wpjam-basic/trunk/static/form.js
r3315366 r3320942 256 256 257 257 if(!this.attr('cols')){ 258 this.css('max-width', '100%').attr('cols', (this.closest('#TB_window')[0] ? 52 : 68));258 this.css('max-width', '100%').attr('cols', (this.closest('#TB_window')[0] ? 52 : 72)); 259 259 } 260 260 } … … 403 403 this.trigger('query_label'); 404 404 }else if(this.is('select')){ 405 this.addClass('hidden').empty().wpjam_select().wpjam_data_type('query', items => (items.length ? this.append(items.map(item => '<option value="'+ item.value+'">'+item.label+'</option>')).removeClass('hidden') : this).trigger('change.wpjam'));405 this.addClass('hidden').empty().wpjam_select().wpjam_data_type('query', items => (items.length ? this.append(items.map(item => '<option value="'+(_.isObject(item) ? item.value : item)+'">'+(_.isObject(item) ? item.label : item)+'</option>')).removeClass('hidden') : this).trigger('change.wpjam')); 406 406 } 407 407 } -
wpjam-basic/trunk/wpjam-basic.php
r3315366 r3320942 4 4 Plugin URI: https://blog.wpjam.com/project/wpjam-basic/ 5 5 Description: WPJAM 常用的函数和接口,屏蔽所有 WordPress 不常用的功能。 6 Version: 6.8. 0.46 Version: 6.8.1 7 7 Requires at least: 6.6 8 8 Tested up to: 6.8
Note: See TracChangeset
for help on using the changeset viewer.