Plugin Directory

Changeset 3320942


Ignore:
Timestamp:
07/02/2025 05:27:16 AM (9 months ago)
Author:
denishua
Message:

version 6.8.1

Location:
wpjam-basic/trunk
Files:
23 edited

Legend:

Unmodified
Added
Removed
  • wpjam-basic/trunk/components/wpjam-cdn.php

    r3315366 r3320942  
    9898
    9999        if(in_array($name, ['exts', 'dirs'])){
    100             $value  = $value ? array_filter(array_map('trim', $value)) : [];
     100            $value  = array_filter(array_map('trim', $value ?: []));
    101101
    102102            if($name == 'exts'){
  • wpjam-basic/trunk/components/wpjam-custom.php

    r3310594 r3320942  
    1212                'head'      => ['title'=>'前台 Head 代码',  'type'=>'textarea'],
    1313                'footer'    => ['title'=>'前台 Footer 代码',    'type'=>'textarea'],
    14                 'custom'    => ['title'=>'文章页代码',   'type'=>'fieldset', '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'=>'只允许']]
    1717                ]]
    1818            ]],
     
    115115    'model'         => 'WPJAM_Custom',
    116116    '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__]
    118118]);
  • wpjam-basic/trunk/extends/mobile-theme.php

    r3310594 r3320942  
    99    public static function get_sections(){
    1010        $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;
    1212
    13         return ['enhance'=>['fields'=>['mobile_stylesheet'=>['title'=>'移动主题', 'options'=>$options]]]];
     13        return wpjam_set('enhance.fields.mobile_stylesheet', ['title'=>'移动主题', 'options'=>$options]);
    1414    }
    1515
    1616    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', [
    1819            'button_text'   => '移动主题',
    1920            'class'         => 'mobile-theme button',
     
    2223            'response'      => 'redirect',
    2324            'callback'      => fn()=> WPJAM_Basic::update_setting('mobile_stylesheet', wpjam_get_data_parameter('stylesheet'))
    24         ]);
     25        ])->get_button(['data'=>['stylesheet'=>'slug']]);
    2526
    26         wpjam_admin('script', <<<'EOD'
     27        wpjam_admin('script', sprintf(<<<'EOD'
    2728        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
    3131            wp.themes.view.Theme.prototype.render = function(){
    32                 original_render.apply(this, arguments);
     32                render.apply(this, arguments);
    3333
    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')));
    4135            };
    4236        }
    43         EOD);
     37        EOD, wpjam_json_encode($mobile), wpjam_json_encode($button)));
    4438
    4539        // wpjam_admin('style', '.mobile-theme{position: absolute; top: 45px; right: 18px;}');
  • wpjam-basic/trunk/extends/wpjam-postviews.php

    r3305886 r3320942  
    143143
    144144        // 不指定 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);
    146146
    147147        $begin  = (int)wpjam_basic_get_setting('views_begin');
     
    151151            $views  = rand(min($begin, $end), max($begin, $end));
    152152       
    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);
    154154        }   
    155155    }
  • wpjam-basic/trunk/extends/wpjam-seo.php

    r3273174 r3320942  
    6464    }
    6565
    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
    6771        if(is_front_page()){
    6872            if(get_query_var('paged') < 2){
     
    8892                    $value  = get_the_excerpt();
    8993                }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')) : '';
    9295                }
    9396            }
     
    9598
    9699        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";
    108103        }
    109104    }
     
    161156    }
    162157
    163     public static function on_wp_head(){
     158    public static function filter_html($html){
    164159        $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(){
    167171        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        }
    184176
    185177        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);
    187179
    188180        if(self::get_setting('sitemap') == 0){
     
    216208
    217209wpjam_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__]
    224215]);
  • wpjam-basic/trunk/extends/wpjam-smtp.php

    r3236921 r3320942  
    99    public static function get_fields(){
    1010        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                 'port'  => ['title'=>'SSL端口',   'type'=>'number',   'class'=>'',            'value'=>'465'],
    15                 'user'  => ['title'=>'邮箱账号',    'type'=>'email',    'class'=>'all-options'],
    16                 'pass'  => ['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'],
    1717            ]],
    1818            '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设置中的邮箱账号']
    2020        ];
    2121    }
  • wpjam-basic/trunk/includes/class-wpjam-admin.php

    r3315366 r3320942  
    2020        if(in_array($key, ['script', 'style'])){
    2121            $key    .= '[]';
     22            $value  = is_array($value) ? implode("\n", $value) : $value;
    2223        }elseif($key == 'pages[]'){
    2324            $slug   = wpjam_pull($value, 'menu_slug');
     
    2829            $value  = array_merge($this->get_arg($key, []), $value, ['subs'=>array_merge($this->get_arg($key.'[subs]', []), $value['subs'])]);
    2930        }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));
    3232        }
    3333
     
    6060
    6161        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});");
    6363        }
    6464
    6565        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)));
    6767        }
    6868    }
     
    146146        }), 'order', 'desc', 10) as $load){
    147147            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                }
    149151            }
    150152
     
    185187            $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);
    186188
    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);
    188190        }
    189191
     
    231233        if(wp_doing_ajax()){
    232234            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
    235238            ]);
    236239
    237240            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']
    239243            ]);
    240244
     
    260264    public function is_allowed($type=''){
    261265        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);
    270266    }
    271267
     
    284280                'page_title'    => $title
    285281            ];
    286         }
    287 
    288         if(!$this->verify_nonce()){
    289             wp_die('invalid_nonce');
    290282        }
    291283
     
    324316        $button = is_array($button) ? $button : [$this->name => $button];
    325317
    326         return wpjam_parse_submit_button($button, $name);
     318        return WPJAM_AJAX::parse_submit_button($button, $name);
    327319    }
    328320
     
    349341                'id'        => $this->form_id ?: 'wpjam_form',
    350342                'data'      => $this->generate_data_attr([], 'form')
    351             ])->append(...(($button = $this->get_submit_button()) ? ['p', ['submit'], $button] : ['']));
     343            ])->append($this->get_submit_button());
    352344        }
    353345    }
     
    363355        return [
    364356            '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'])+[
    367359            'title'     => $this->page_title ?: $this->button_text,
    368360            'data'      => wp_parse_args(($args['data'] ?? []), ($this->data ?: [])),
    369             'direct'    => $this->direct,
    370             'confirm'   => $this->confirm
    371361        ] : []);
    372362    }
     
    547537        }
    548538
    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        }
    550542    }
    551543
     
    630622            wpjam_admin('load');
    631623        }elseif($type){
    632             $object = $object ?: $this->page_object($type, $name);
     624            $object ??= $this->page_object($type, $name);
    633625            $hook   = 'load-'.wpjam_admin('page_hook');
    634626
     
    654646    private function preprocess($type, $name){
    655647        $class  = ['form'=>'WPJAM_Page_Action', 'option'=>'WPJAM_Option_Setting'][$type] ?? '';
    656         $object = $class ? $class::get($name) : '';
     648        $object = $class ? $class::get($name) : null;
    657649
    658650        if($object){
     
    722714            }
    723715
    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            }
    725719
    726720            return new WPJAM_List_Table($args+array_filter([
     
    794788        if($method == 'callback'){  // 只有 POST 方法提交才处理,自动草稿、自动保存和预览情况下不处理
    795789            if($_SERVER['REQUEST_METHOD'] != 'POST'
    796                 || get_post_status($post_id) == 'auto-draft'
     790                || get_post_status($args[0]) == 'auto-draft'
    797791                || (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)
    798792                || (!empty($_POST['wp-preview']) && $_POST['wp-preview'] == 'dopreview')
     
    877871
    878872            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'])]);
    880874            }
    881875
     
    900894
    901895            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                }
    903899
    904900                wpjam_unregister_list_table_action('inline hide-if-no-js');
     
    10941090        }
    10951091
    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));
    10971093        $data   = $total = [];
    10981094
  • wpjam-basic/trunk/includes/class-wpjam-api.php

    r3315366 r3320942  
    133133
    134134    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());
    136136        array_map(fn($filter)=> add_filter($filter, [self::get_instance(), 'filter_'.$filter], 11), ['query_vars', 'request']);
    137137
     
    407407    public function get_tabbar($page_key=''){
    408408        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);
    410410        }
    411411
     
    417417    public function get_page($page_key=''){
    418418        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);
    423423    }
    424424
     
    14061406            }else{
    14071407                return [
    1408                     'nonce'     => '验证失败,请刷新重试。',
    14091408                    'code'      => '验证码错误。',
    14101409                    'password'  => '两次输入的密码不一致。'
  • wpjam-basic/trunk/includes/class-wpjam-args.php

    r3315366 r3320942  
    1717    }
    1818
    19     public function chain($value){
    20         return new WPJAM_Chainable($value, $this);
    21     }
    22 
    2319    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;
    2721    }
    2822
     
    3428        static $methods = [];
    3529
    36         $called = self::get_called();
    37         $name   = $called.':'.$method;
    38 
    3930        if($action == 'add'){
    4031            if(is_closure($args[0])){
    41                 $methods[$name] = $args[0];
     32                $methods[$method]   = $args[0];
    4233            }
    4334        }elseif($action == 'remove'){
    44             unset($methods[$name]);
     35            unset($methods[$method]);
    4536        }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);
    4738        }
    4839    }
     
    5647    }
    5748
    58     public static function get_called($key=null){
     49    public static function get_called(){
    5950        return strtolower(get_called_class());
    6051    }
     
    9081    }
    9182
    92     public function is_keyable($key){
    93         return is_int($key) || is_string($key) || is_null($key);
    94     }
    95 
    9683    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];
    9986            $key    = null;
    100         }else{
    101             $item   = array_shift($args);
    102         }
    103 
     87        }
     88
     89        $item   = array_shift($args);
    10490        $field  = array_shift($args) ?: '';
    10591
     
    290276
    291277    protected function filter_args(){
    292         if(!$this->args && !is_array($this->args)){
     278        if(!$this->args){
    293279            $this->args = [];
    294280        }
     
    301287    }
    302288
    303     public function set_args($args){
    304         $this->args = $args;
    305 
    306         return $this;
    307     }
    308 
    309289    public function update_args($args, $replace=true){
    310290        $this->args = ($replace ? 'array_replace' : 'wp_parse_args')($this->get_args(), $args);
     
    318298        if(in_array($action, ['parse', 'callback'], true)){
    319299            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;
    323301            }else{
    324302                $value  = $this->bind_if_closure($value);
     
    427405
    428406    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)){
    432410            return $called(...$args);
    433411        }
    434412
    435         if(is_string($method) && str_starts_with($method, 'filter_')){
     413        if(str_starts_with($method, 'filter_')){
    436414            return array_shift($args);
    437415        }   
     
    501479
    502480    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);
    505485        }
    506486
     
    550530    }
    551531
    552     public static function get_group($args=[]){
     532    public static function get_group($args){
    553533        return WPJAM_Register_Group::instance($args);
    554534    }
    555535
    556536    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){
    560538            $group  = static::get_group(['called'=>$called, 'name'=>strtolower($called)]);
    561539
     
    570548    }
    571549
    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);
    580552    }
    581553
     
    631603
    632604    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        }   
    640614    }
    641615
     
    703677    }
    704678
    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 
    711679    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);
    715681    }
    716682
     
    718684        $type   = array_find(['filter', 'get'], fn($type)=> str_starts_with($method, $type.'_'));
    719685
    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        }   
    735701
    736702        if($type == 'filter'){
     
    805771        if($this->admin){
    806772            $data   = wpjam_if_error(wpjam_fields($this->fields)->catch('get_parameter', 'POST'), 'send');
     773            $verify = wpjam_get($data, 'action_type') !== 'form';
    807774        }else{
    808775            $data   = array_merge(wpjam_get_data_parameter(), wpjam_except(wpjam_get_post_parameter(), ['action', 'defaults', 'data', '_ajax_nonce']));
    809776            $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
    817790        return wpjam_send_json(wpjam_catch($this->callback, $data, $this->name));
    818791    }
    819792
    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        }
    824816    }
    825817
     
    840832        }
    841833
    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']);
    854836        }
    855837
    856838        return wpjam('ajax', $name, $args);
    857     }
    858 
    859     public static function get($name){
    860         return wpjam('ajax', $name);
    861839    }
    862840}
     
    969947        foreach($items as $i => &$item){
    970948            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);
    976950            }
    977951
     
    998972        if($args['sum']){
    999973            $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);
    1002977        }
    1003978
     
    10931068
    10941069    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        }
    11101081
    11111082        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            }
    11171100
    11181101            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];
    11261107    }
    11271108
     
    14071388    }
    14081389}
    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  
    470470            }
    471471
    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);
    473473            $rest   = $this->show_in_rest;
    474474
     
    11001100                    $type   = 'hidden';
    11011101                    $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)];
    11031103                }
    11041104
     
    11521152        return new WPJAM_Field($field);
    11531153    }
    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     }
    11621154}
    11631155
  • wpjam-basic/trunk/includes/class-wpjam-list-table.php

    r3315366 r3320942  
    2020        $this->_args    = $args;
    2121        $this->screen   = $screen = get_current_screen();
    22 
    23         $args   = compact('screen');
    24         $style  = [$this->style];
    2522
    2623        foreach($this->get_objects('action') as $object){
     
    5552
    5653        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];
    5855        }else{
    5956            if(!$this->builtin && !empty($args['bulk_actions'])){
     
    6259
    6360            foreach($this->get_objects('column') as $object){
    64                 $style[]= $object->style;
    6561                $key    = $object->name;
    6662                $data   = array_filter(wpjam_pick($object, ['description', 'sticky', 'nowrap', 'format', 'precision', 'conditional_styles']));
     
    7167                    $args['sortable_columns'][$key] = [$key, true];
    7268                }
    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);
    7775        wpjam_admin('vars[list_table]', fn()=> $this->get_setting());
    7876        wpjam_admin('vars[page_title_action]', fn()=> $this->get_action('add', ['class'=>'page-title-action']) ?: '');
     
    8280        add_filter('manage_'.$screen->id.'_sortable_columns', [$this, 'filter_sortable_columns']);
    8381
    84         $this->_args    = array_merge($this->_args, $args);
     82        $this->_args    = array_merge($this->_args, $args+['screen'=>$screen]);
    8583
    8684        if($this->builtin){
     
    124122                $this->filterable   = array_merge($value, array_keys($fields));
    125123
    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);
    127125
    128126                return $this->$name = $fields+(($fields && !$this->builtin && $this->sortable_columns) ? [
     
    267265
    268266    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);
    270268    }
    271269
     
    303301        $attr   = $id ? ['id'=>$this->singular.'-'.str_replace('.', '-', $id), 'data'=>['id'=>$id]] : [];
    304302
    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.'」不存在'] : []);
    306304
    307305        $this->before_single_row_by_model($raw);
     
    521519
    522520        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            ]);
    524525        }
    525526
     
    616617
    617618    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'] : []);
    622620    }
    623621
     
    738736    }
    739737
    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 
    748738    public function callback($args){
    749739        if(is_array($args)){
     
    858848            || ($this->bulk === 'export' && $args['bulk'])
    859849        )){
    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))];
    861851            $args   += $submit_name != $this->name ? ['submit_name'=>$submit_name] : [];   
    862852
     
    870860        if($type == 'form'){
    871861            return $response+['form'=>$this->get_form($form_args, $type)];
    872         }
    873 
    874         if(!$this->verify_nonce($args)){
    875             wp_die('invalid_nonce');
    876862        }
    877863
     
    992978        $fields = $object->get_fields($args, false, $type)->render();
    993979        $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')]);
    998983    }
    999984
     
    10441029        $button = is_array($button) ? $button : [$this->name => $button];
    10451030
    1046         return wpjam_parse_submit_button($button, $name);
     1031        return WPJAM_AJAX::parse_submit_button($button, $name);
    10471032    }
    10481033
     
    11231108    public function generate_data_attr($args=[], $type='button'){
    11241109        $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))];
    11261111        $attr   += $this->overall ? [] : ($args['bulk'] ? wpjam_pick($args, ['ids'])+wpjam_pick($this, ['bulk', 'title']) : wpjam_pick($args, ['id']));
    11271112
  • wpjam-basic/trunk/includes/class-wpjam-model.php

    r3310594 r3320942  
    396396
    397397        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;
    399399        }
    400400
     
    744744        if($orderby){
    745745            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));
    748747            }elseif(str_contains($orderby, ',') || (str_contains($orderby, '(') && str_contains($orderby, ')'))){
    749748                $orderby    = $orderby;
     
    819818            return sprintf('RAND(%s)', (int)$matches[1]);
    820819        }elseif(str_ends_with($orderby, '__in')){
    821             return '';
     820            return null;
    822821            // $field   = str_replace('__in', '', $orderby);
    823822        }
     
    846845
    847846        if($orderby == 'meta_value_num' || $orderby == 'meta_value'){
    848             return '';
     847            return null;
    849848        }
    850849
     
    13731372
    13741373        if($this->item_type == 'array'){
    1375             $this->lazyload_key = wpjam_array($this->lazyload_key);
     1374            $this->lazyload_key = (array)$this->lazyload_key;
    13761375            $this->primary_key  ??= 'id';
    13771376        }else{
  • wpjam-basic/trunk/includes/class-wpjam-post.php

    r3315366 r3320942  
    475475
    476476    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);
    478478
    479479        if(isset($data['post_content']) && is_array($data['post_content'])){
     
    680680
    681681        if($key == 'model'){
    682             if(!$value || !class_exists($value) || !is_subclass_of($value, 'WPJAM_Post')){
     682            if(!$value || !class_exists($value)){
    683683                return 'WPJAM_Post';
    684684            }
     
    15091509                $clauses['join']    .= "LEFT JOIN {$wpdb->postmeta} jam_pm ON {$wpdb->posts}.ID = jam_pm.post_id AND jam_pm.meta_key = '{$meta_key}' ";
    15101510                $clauses['orderby'] = "(COALESCE(jam_pm.meta_value, 0)+0) {$order}, " . $clauses['orderby'];
     1511                $clauses['groupby'] = "{$wpdb->posts}.ID";
    15111512            }elseif(in_array($orderby, ['', 'date', 'post_date'])){
    15121513                $clauses['orderby'] .= ", {$wpdb->posts}.ID {$order}";
  • wpjam-basic/trunk/includes/class-wpjam-setting.php

    r3310594 r3320942  
    306306    public function page_load(){
    307307        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            ]);
    309313        }
    310314    }
    311315
    312316    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 
    321317        flush_rewrite_rules();
    322318
     
    374370        ];
    375371
    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            }
    392384        }else{
    393385            if($args['option_type'] == 'array' && !doing_filter('sanitize_option_'.$name) && is_null(get_option($name, null))){
     
    395387            }
    396388
    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;
    403393    }
    404394}
     
    406396class WPJAM_Option_Model{
    407397    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;
    411399    }
    412400
     
    514502
    515503    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);
    517505    }
    518506
  • wpjam-basic/trunk/includes/class-wpjam-term.php

    r3315366 r3320942  
    491491
    492492        if($key == 'model'){
    493             if(!$value || !class_exists($value) || !is_subclass_of($value, 'WPJAM_Term')){
     493            if(!$value || !class_exists($value)){
    494494                return 'WPJAM_Term';
    495495            }
     
    965965        }
    966966
    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);
    969968        $args       = array_merge($args, $mapping);
    970969        $number     = (int)wpjam_pull($args, 'number');
  • wpjam-basic/trunk/includes/class-wpjam-user.php

    r3305886 r3320942  
    771771                    'title'     => '绑定账号',
    772772                    '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)
    774774                ])
    775775            ]);
  • wpjam-basic/trunk/public/wpjam-compat.php

    r3315366 r3320942  
    181181function wpjam_remove_postfix($str, $postfix, &$removed=false){
    182182    return wpjam_remove_suffix($str, $postfix, $removed);
     183}
     184
     185function wpjam_get_plain_text($text){
     186    return $text ? trim(preg_replace('/\s+/', ' ', str_replace(['"', '\'', "\r\n", "\n"], ['', '', ' ', ' '], wp_strip_all_tags($text)))) : $text;
    183187}
    184188
  • wpjam-basic/trunk/public/wpjam-functions.php

    r3315366 r3320942  
    395395        $posts  = WPJAM_Post::get_by_ids($ids);
    396396
    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;
    398398    }
    399399
     
    864864
    865865function 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);
    874869}
    875870
  • wpjam-basic/trunk/public/wpjam-route.php

    r3315366 r3320942  
    239239    if(count($args) > 1 || ($args && (is_string($args[0]) || is_bool($args[0])))){
    240240        $group  = array_shift($args);
     241        $cb     = array_shift($args);
     242        $arg    = array_shift($args);
    241243        $fix    = is_bool($group) ? ($group ? 'site_' : '').'transient' : '';
    242244        $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;
    245247
    246248        if($expire === -1){
    247249            return $fix ? ('delete_'.$fix)($key) : wp_cache_delete($key, $group);
    248250        }
    249 
    250         $force  = array_shift($args);
     251       
     252        $force  = wpjam_get($args, 'force');
    251253        $value  = $fix ? ('get_'.$fix)($key) : wp_cache_get($key, $group, ($force === 'get' || $force === true));
    252254
    253         if($cb && ($value === false || ($force === 'set' || $force === true))){
     255        if($cb && ($value === false || $force === 'set' || $force === true)){
    254256            $value  = $cb($value, $key, $group);
    255257
     
    269271}
    270272
    271 function wpjam_transient($name, $callback, $expire=86400, $global=false, $force=false){
    272     return wpjam_cache($name, (bool)$global, $callback, $expire, $force);
     273function wpjam_transient($name, $callback, $args=[], $global=false){
     274    return wpjam_cache($name, (bool)$global, $callback, $args);
    273275}
    274276
    275277function 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);
    279279}
    280280
    281281function 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));
    290285}
    291286
    292287function 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);
    301291}
    302292
     
    659649
    660650    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);
    662652    }
    663653
     
    685675            wpjam_admin($type.'_load[]', $args);
    686676        }
    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 ?? []);
    703677    }
    704678
  • wpjam-basic/trunk/public/wpjam-utils.php

    r3315366 r3320942  
    369369
    370370                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);
    372372                }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                    }
    376380                }
    377381            }
     
    545549}
    546550
    547 function wpjam_array($arr=null, $callback=null){
     551function wpjam_array($arr=null, $callback=null, $skip_null=false){
    548552    if(is_object($arr)){
    549553        if(method_exists($arr, 'to_array')){
     
    561565    }
    562566
    563     if($callback && is_callable($callback)){
     567    if($data && $callback && is_callable($callback)){
    564568        foreach($data as $k => $v){
    565569            $result = $callback($k, $v);
    566570
    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;
    574574                }
     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;
    575591            }
    576592        }
     
    793809
    794810    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        ], []);
    796817    }elseif(is_callable($args[0]) || is_string($args[0])){
     818        $field  = $args[0];
    797819        $order  = $args[1] ?? '';
    798820
    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));
    801823            $flag   = $args[2] ?? SORT_NUMERIC;
    802824        }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;
    808828        }
    809829
     
    934954        }
    935955
    936         if(str_ends_with($key, '[]')){
     956        if($key === '[]'){
     957            $arr[]  = $value;
     958
     959            return $arr;
     960        }elseif(str_ends_with($key, '[]')){
    937961            $current    = wpjam_get($arr, $key);
    938962            $current[]  = $value;
     
    11701194}
    11711195
    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 
    11771196//获取第一段
    11781197function wpjam_get_first_p($text){
  • wpjam-basic/trunk/readme.txt

    r3305886 r3320942  
    5454== Changelog ==
    5555
     56= 6.8.1 =
     57* wpjam_set 支持 [] 模式新增元素
     58* 全面优化 WPJAM_AJAX class,整合后台的 AJAX 操作
     59* 优化 wpjam_sort 排序函数
     60* 其他优化和bug修复
     61
    5662= 6.8 =
    5763* 全面优化 wpjam_try / wpjam_catch 等高阶函数
     
    6975* 新增函数 wpjam_reduce
    7076* 新增函数 wpjam_bettwen
    71 * 其他优化和bug修复
    7277
    7378= 6.6 =
  • wpjam-basic/trunk/static/form.js

    r3315366 r3320942  
    256256
    257257            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));
    259259            }
    260260        }
     
    403403                        this.trigger('query_label');
    404404                    }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'));
    406406                    }
    407407                }
  • wpjam-basic/trunk/wpjam-basic.php

    r3315366 r3320942  
    44Plugin URI: https://blog.wpjam.com/project/wpjam-basic/
    55Description: WPJAM 常用的函数和接口,屏蔽所有 WordPress 不常用的功能。
    6 Version: 6.8.0.4
     6Version: 6.8.1
    77Requires at least: 6.6
    88Tested up to: 6.8
Note: See TracChangeset for help on using the changeset viewer.