Plugin Directory

Changeset 3310594


Ignore:
Timestamp:
06/12/2025 02:57:33 PM (10 months ago)
Author:
denishua
Message:

version 6.8.0.1

Location:
wpjam-basic/trunk
Files:
24 edited

Legend:

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

    r3305886 r3310594  
    1010            'wpjam-icons'   => ['menu_title'=>'图标列表',       'order'=>9, 'tabs'=>['dashicons'=>['title'=>'Dashicons', 'function'=>[self::class, 'dashicons_page']]]],
    1111        ] as $slug => $args){
    12             if($args['order'] < 10 || wpjam_filter(wpjam_admin('tabs') ?: [], fn($v)=> wpjam_get($v, 'plugin_page') == $slug)){
     12            if($args['order'] < 10 || wpjam_filter(wpjam_admin('tabs[]'), fn($v)=> wpjam_get($v, 'plugin_page') == $slug)){
    1313                wpjam_add_menu_page($slug, $args+[
    1414                    'parent'    => 'wpjam-basic',
     
    2727
    2828        if(get_transient('wpjam_basic_verify')){
    29             wpjam_admin('pages', wpjam_except(wpjam_admin('pages'), 'wpjam-basic.subs.wpjam-about'));
     29            wpjam_admin('pages[wpjam-basic][subs][wpjam-about]', null);
    3030        }elseif(WPJAM_Verify::verify()){
    3131            if(isset($_GET['unbind_wpjam_user'])){
     
    3535            }
    3636        }else{
    37             wpjam_admin('pages', wpjam_set(wpjam_admin('pages'), 'wpjam-basic.subs', ['wpjam-verify'=> [
     37            wpjam_admin('pages[wpjam-basic][subs]', ['wpjam-verify'=> [
    3838                'menu_title'    => '扩展管理',
    3939                'page_title'    => '验证 WPJAM',
    4040                'function'      => 'form',
    4141                'model'         => 'WPJAM_Verify'
    42             ]]));
     42            ]]);
    4343        }
    4444    }
     
    148148            ]))->page_load();
    149149
    150             wpjam_admin('add', 'style', [
     150            wpjam_admin('style', [
    151151                '#dashboard_wpjam .inside{margin:0; padding:0;}',
    152152                'a.jam-post {border-bottom:1px solid #eee; margin: 0 !important; padding:6px 0; display: block; text-decoration: none; }',
     
    160160
    161161            if($base){
    162                 wpjam_admin('add', 'script', "
     162                wpjam_admin('script', "
    163163                $('tr.plugin-update-tr').each(function(){
    164164                    let detail_link = $(this).find('a.open-plugin-details-modal');
     
    263263
    264264    public static function get_form(){
    265         wpjam_admin('add', 'style', '.form-table th{width: 100px;}');
     265        wpjam_admin('style', '.form-table th{width: 100px;}');
    266266
    267267        $qrcode = wpjam_tag('img', ['src'=>'https://open.weixin.qq.com/qr/code?username=wpjamcom', 'style'=>'max-width:250px;'])->wrap('p')->before('p', [], '使用微信扫描下面的二维码:');
  • wpjam-basic/trunk/components/wpjam-custom.php

    r3305886 r3310594  
    4444        }
    4545
    46         if(in_array($name, ['head', 'footer']) && self::get_setting('custom_post') && is_singular()){
    47             echo get_post_meta(get_the_ID(), 'custom_'.$name, true);
     46        if(in_array($name, ['head', 'footer']) && is_singular() && self::get_setting('custom_post')){
     47            if($value = get_post_meta(get_the_ID(), 'custom_'.$name, true)){
     48                if($name == 'head'){
     49                    add_action('wp_'.$name, fn()=> wpjam_echo($value), 99);
     50                }else{
     51                    echo $value;
     52                }
     53            }
    4854        }
    4955    }
  • wpjam-basic/trunk/components/wpjam-posts.php

    r3305886 r3310594  
    171171        if($base == 'post'){
    172172            if(self::get_setting('disable_trackbacks')){
    173                 $style[]    = 'label[for="ping_status"]{display:none !important;}';
     173                wpjam_admin('style', 'label[for="ping_status"]{display:none !important;}');
    174174            }
    175175
    176176            if(self::get_setting('disable_autoembed') && $screen->is_block_editor){
    177                 $scripts[]  = "wp.domReady(()=> wp.blocks.unregisterBlockType('core/embed'));\n";
     177                wpjam_admin('script', "wp.domReady(()=> wp.blocks.unregisterBlockType('core/embed'));\n");
    178178            }
    179179        }elseif(in_array($base, ['edit', 'upload'])){
    180             $style  = ['.fixed .column-date{width:8%;}'];
     180            wpjam_admin('style', '.fixed .column-date{width:8%;}');
     181
    181182            $ptype  = $screen->post_type;
    182183            $object = wpjam_admin('type_object');
     
    225226                }
    226227
    227                 $style[]    = '#bulk-titles, ul.cat-checklist{height:auto; max-height: 14em;}';
     228                wpjam_admin('style', '#bulk-titles, ul.cat-checklist{height:auto; max-height: 14em;}');
    228229
    229230                if($ptype == 'page'){
    230                     $style[]    = '.fixed .column-template{width:15%;}';
     231                    wpjam_admin('style', '.fixed .column-template{width:15%;}');
    231232
    232233                    wpjam_register_posts_column('template', '模板', 'get_page_template_slug');
     
    242243
    243244            if($width_columns){
    244                 $style[]    = implode(',', $width_columns).'{width:'.(['14%', '12%', '10%', '8%', '7%'][count($width_columns)-1] ?? '6%').'}';
     245                wpjam_admin('style', implode(',', $width_columns).'{width:'.(['14%', '12%', '10%', '8%', '7%'][count($width_columns)-1] ?? '6%').'}');
    245246            }
    246247        }elseif(in_array($base, ['edit-tags', 'term'])){
     
    248249                add_filter('wpjam_single_row',  [self::class, 'filter_single_row'], 10, 2);
    249250
    250                 $style  = [
     251                wpjam_admin('style', [
    251252                    '.fixed th.column-slug{width:16%;}',
    252253                    '.fixed th.column-description{width:22%;}',
    253254                    '.form-field.term-parent-wrap p{display: none;}',
    254255                    '.form-field span.description{color:#666;}'
    255                 ];
    256             }
    257 
    258             $object = wpjam_admin('tax_object');
    259             $style  = array_merge($style ?? [], wpjam_map(['slug', 'description', 'parent'], fn($v)=> $object->supports($v) ? '' : '.form-field.term-'.$v.'-wrap{display: none;}'));   
     256                ]);
     257            }
     258
     259            array_map(fn($v)=> wpjam_admin('tax_object')->supports($v) ? '' : wpjam_admin('style', '.form-field.term-'.$v.'-wrap{display: none;}'), ['slug', 'description', 'parent']);
    260260        }
    261261
    262262        if($base == 'edit-tags' || ($base == 'edit' && !self::is_wc_shop($ptype))){
    263263            if(self::get_setting('post_list_ajax', 1)){
    264                 $scripts[]  = <<<'EOD'
     264                wpjam_admin('script', <<<'EOD'
    265265                $(window).load(function(){
    266266                    wpjam.delegate('#the-list', '.editinline');
    267267                    wpjam.delegate('#doaction');
    268268                });
    269                 EOD;
     269                EOD);
    270270            }else{
    271                 $scripts[]  = "wpjam.list_table.ajax    = false;\n";
     271                wpjam_admin('script', "wpjam.list_table.ajax    = false;\n");
    272272            }
    273273
    274274            if($base == 'edit'){
    275                 $scripts[]  = <<<'EOD'
     275                wpjam_admin('script', <<<'EOD'
    276276                wpjam.add_extra_logic(inlineEditPost, 'setBulk', ()=> $('#the-list').trigger('bulk_edit'));
    277277
     
    279279                    return ($('#the-list').trigger('quick_edit', typeof(id) === 'object' ? this.getId(id) : id), false);
    280280                });
    281                 EOD;
    282             }
    283         }
    284 
    285         if(!empty($scripts)){
    286             wpjam_admin('add', 'script', $scripts);
    287         }
    288 
    289         if(!empty($style)){
    290             wpjam_admin('add', 'style', $style);
     281                EOD);
     282            }
    291283        }
    292284    }
  • wpjam-basic/trunk/extends/baidu-zz.php

    r3305886 r3310594  
    197197                add_action('post_submitbox_misc_actions',   [self::class, 'on_post_submitbox_misc_actions'],11);
    198198
    199                 wpjam_admin('add', 'style', '#post-body #baidu_zz_section:before{content: "\f103"; color:#82878c; font: normal 20px/1 dashicons; speak: none; display: inline-block; margin-left: -1px; padding-right: 3px; vertical-align: top; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }');
     199                wpjam_admin('style', '#post-body #baidu_zz_section:before{content: "\f103"; color:#82878c; font: normal 20px/1 dashicons; speak: none; display: inline-block; margin-left: -1px; padding-right: 3px; vertical-align: top; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }');
    200200            }
    201201        }
  • wpjam-basic/trunk/extends/mobile-theme.php

    r3305886 r3310594  
    2424        ]);
    2525
    26         wpjam_admin('add', 'script', <<<'EOD'
     26        wpjam_admin('script', <<<'EOD'
    2727        if(wp && wp.Backbone && wp.themes && wp.themes.view.Theme){
    2828            let original_render = wp.themes.view.Theme.prototype.render;
     
    4343        EOD);
    4444
    45         // wpjam_admin('add', 'style', '.mobile-theme{position: absolute; top: 45px; right: 18px;}');
     45        // wpjam_admin('style', '.mobile-theme{position: absolute; top: 45px; right: 18px;}');
    4646    }
    4747
  • wpjam-basic/trunk/extends/quick-excerpt.php

    r3305886 r3310594  
    1818
    1919        if(!wp_doing_ajax()){
    20             wpjam_admin('add', 'script', <<<'EOD'
     20            wpjam_admin('script', <<<'EOD'
    2121            $('body').on('quick_edit', '#the-list', function(event, id){
    2222                let edit_row    = $('#edit-'+id);
  • wpjam-basic/trunk/extends/wpjam-toc.php

    r3273174 r3310594  
    66Version: 1.0
    77*/
    8 class WPJAM_Toc_Setting extends WPJAM_Option_Model{
     8class WPJAM_Toc extends WPJAM_Option_Model{
    99    public static function get_fields(){
    1010        $fields = [
     
    2828    }
    2929
    30     public static function filter_content($content){
    31         if(self::get_setting('position') == 'shortcode' && strpos($content, '[toc]') === false){
    32             return $content;
     30    public static function get_depth($post_id){
     31        if(self::get_setting('individual', 1)){
     32            if(get_post_meta($post_id, 'toc_hidden', true)){
     33                return;
     34            }
     35
     36            if(metadata_exists('post', $post_id, 'toc_depth')){
     37                return get_post_meta($post_id, 'toc_depth', true);
     38            }
    3339        }
    3440
    35         $post_id    = get_the_ID();
     41        return self::get_setting('depth', 6);
     42    }
    3643
    37         if(doing_filter('get_the_excerpt') || !is_singular() || $post_id != get_queried_object_id()){
    38             return $content;
     44    public static function render(){
     45        if(!wpjam('get', 'toc')){
     46            return '';
    3947        }
    4048
    41         $depth  = self::get_setting('depth', 6);
     49        $index  = '';
     50        $path   = [];
    4251
    43         if(self::get_setting('individual', 1)){
    44             if(get_post_meta($post_id, 'toc_hidden', true)){
     52        foreach(wpjam('get', 'toc') as $item){
     53            if($path){
     54                if(end($path) < $item['depth']){
     55                    $index  .= "\n<ul>\n";
     56                }elseif(end($path) == $item['depth']){
     57                    $index  .= "</li>\n";
     58
     59                    array_pop($path);
     60                }else{
     61                    while(end($path) > $item['depth']){
     62                        $index  .= "</li>\n</ul>\n";
     63
     64                        array_pop($path);
     65                    }
     66                }
     67            }
     68
     69            $index  .= '<li class="toc-level'.$item['depth'].'"><a href="#'.$item['id'].'">'.$item['text'].'</a>';
     70            $path[] = $item['depth'];
     71        }
     72
     73        $index  .= "</li>\n".str_repeat("</li>\n</ul>\n", count($path)-1);
     74        $index  = "<ul>\n".$index."</ul>\n";
     75
     76        return '<div id="toc">'."\n".'<p class="toc-title"><strong>文章目录</strong><span class="toc-controller toc-controller-show">[隐藏]</span></p>'."\n".$index.'</div>'."\n";
     77    }
     78
     79    public static function add_item($m){
     80        $attr   = $m[2] ? shortcode_parse_atts($m[2]) : [];
     81        $attr   = wp_parse_args($attr, ['class'=>'', 'id'=>'']);
     82
     83        if(!$attr['class'] || !str_contains($attr['class'], 'toc-noindex')){
     84            $attr['class']  .= ($attr['class'] ? ' ' : '').'toc-index';
     85            $attr['id']     = $attr['id'] ?: 'toc_'.(count(wpjam('get', 'toc'))+1);
     86
     87            wpjam('add', 'toc', ['text'=>trim(strip_tags($m[3])), 'depth'=>$m[1],   'id'=>$attr['id']]);
     88        }
     89
     90        return wpjam_tag('h'.$m[1], $attr, $m[3]);
     91    }
     92
     93    public static function add_hooks(){
     94        add_filter('the_content', function($content){
     95            if(!is_singular()
     96                || get_the_ID() != get_queried_object_id()
     97                || doing_filter('get_the_excerpt')
     98                || (self::get_setting('position') == 'shortcode' && !str_contains($content, '[toc]'))
     99            ){
    45100                return $content;
    46101            }
    47102
    48             if(metadata_exists('post', $post_id, 'toc_depth')){
    49                 $depth = get_post_meta($post_id, 'toc_depth', true);
    50             }
    51         }
     103            $depth      = self::get_depth(get_the_ID());
     104            $content    = wpjam_preg_replace('#<h([1-'.$depth.'])\b([^>]*)>(.*?)</h\1>#', fn($m)=> self::add_item($m), $content);
    52105
    53         $object = wpjam_get_instance('toc', $post_id, fn()=> new WPJAM_Toc($content, $depth));
    54         $toc    = $object->get_toc();
    55 
    56         if($toc){
    57             if(strpos($content, '[toc]') !== false){
    58                 $content    = str_replace('[toc]', $toc, $content);
    59             }elseif(self::get_setting('position', 'content') == 'content'){
    60                 $content    = $toc.$content;
    61             }
    62         }
    63 
    64         return $content;
    65     }
    66 
    67     public static function on_head(){
    68         if(is_singular()){
    69             if(!current_theme_supports('script', 'toc')){
    70                 echo '<script type="text/javascript">'."\n".self::get_setting('script')."\n".'</script>'."\n"; 
     106            if($toc = self::render()){
     107                if(str_contains($content, '[toc]')){
     108                    return str_replace('[toc]', $toc, $content);
     109                }elseif(self::get_setting('position', 'content') == 'content'){
     110                    return $toc.$content;
     111                }
    71112            }
    72113
    73             if(!current_theme_supports('style', 'toc')){
    74                 echo '<style type="text/css">'."\n".self::get_setting('css')."\n".'</style>'."\n";
    75             }
    76         }
    77     }
    78 
    79     public static function add_hooks(){
    80         add_filter('the_content',   [self::class, 'filter_content'], 11);
     114            return $content;
     115        }, 11);
    81116
    82117        if(self::get_setting('auto', 1)){
    83             add_action('wp_head',   [self::class, 'on_head']);
     118            add_action('wp_head', function(){
     119                if(is_singular()){
     120                    if(!current_theme_supports('script', 'toc')){
     121                        echo '<script type="text/javascript">'."\n".self::get_setting('script')."\n".'</script>'."\n"; 
     122                    }
     123
     124                    if(!current_theme_supports('style', 'toc')){
     125                        echo '<style type="text/css">'."\n".self::get_setting('css')."\n".'</style>'."\n";
     126                    }
     127                }
     128            });
    84129        }
    85130
     
    99144}
    100145
    101 class WPJAM_Toc{
    102     protected $items    = [];
    103 
    104     public function __construct(&$content, $depth=6){
    105         $content    = wpjam_preg_replace('#<h([1-'.$depth.'])\b([^>]*)>(.*?)</h\1>#', fn($m)=> $this->add_item($m), $content);
    106     }
    107 
    108     public function get_toc(){
    109         if(empty($this->items)){
    110             return '';
    111         }
    112 
    113         $index      = '<ul>'."\n";
    114         $prev_depth = 0;
    115         $to_depth   = 0;
    116 
    117         foreach($this->items as $i => $item){
    118             $depth  = $item['depth'];
    119 
    120             if($prev_depth){
    121                 if($depth == $prev_depth){
    122                     $index .= '</li>'."\n";
    123                 }elseif($depth > $prev_depth){
    124                     $to_depth++;
    125                     $index .= "\n".'<ul>'."\n";
    126                 }else{
    127                     $to_depth2 = ($to_depth > ($prev_depth - $depth))? ($prev_depth - $depth) : $to_depth;
    128 
    129                     if($to_depth2){
    130                         for($i=0; $i<$to_depth2; $i++){
    131                             $index .= '</li>'."\n".'</ul>'."\n";
    132                             $to_depth--;
    133                         }
    134                     }
    135 
    136                     $index .= '</li>'."\n";
    137                 }
    138             }
    139 
    140             $prev_depth = $depth;
    141 
    142             $index .= '<li class="toc-level'.$depth.'"><a href="#'.$item['id'].'">'.$item['text'].'</a>';
    143         }
    144 
    145         for($i=0; $i<=$to_depth; $i++){
    146             $index .= '</li>'."\n".'</ul>'."\n";
    147         }
    148 
    149         return '<div id="toc">'."\n".'<p class="toc-title"><strong>文章目录</strong><span class="toc-controller toc-controller-show">[隐藏]</span></p>'."\n".$index.'</div>'."\n";
    150     }
    151 
    152     public function add_item($matches){
    153         $attr   = $matches[2] ? shortcode_parse_atts($matches[2]) : [];
    154 
    155         $attr['class']  = $attr['class'] ?? '';
    156         $attr['class']  = wp_parse_list($attr['class']);
    157 
    158         if(!$attr['class'] || !in_array('toc-noindex', $attr['class'])){
    159             $attr['class'][]= 'toc-index';
    160             $attr['id']     = !empty($attr['id']) ? $attr['id'] : 'toc_'.(count($this->items)+1);
    161 
    162             $this->items[]  = ['text'=>trim(strip_tags($matches[3])), 'depth'=>$matches[1], 'id'=>$attr['id']];
    163         }
    164 
    165         return wpjam_tag('h'.$matches[1], $attr, $matches[3]);
    166     }
    167 }
    168 
    169146wpjam_register_option('wpjam-toc', [
    170     'model'     => 'WPJAM_Toc_Setting',
     147    'model'     => 'WPJAM_Toc',
    171148    'title'     => '文章目录',
    172149    'menu_page' => ['tab_slug'=>'toc', 'plugin_page'=>'wpjam-posts', 'summary'=> __FILE__]
     
    174151
    175152function wpjam_get_toc(){
    176     $post_id    = get_the_ID();
    177     $object     = $post_id ? wpjam_get_instance('toc', $post_id) : null;
    178 
    179     return $object ? $object->get_toc() : '';
     153    return is_singular() ? WPJAM_Toc::render() : '';
    180154}
    181 
  • wpjam-basic/trunk/includes/class-wpjam-admin.php

    r3305886 r3310594  
    11<?php
    22class WPJAM_Admin extends WPJAM_Args{
    3     use WPJAM_Items_Trait;
     3    public function call($key, ...$args){
     4        if(method_exists($this, $key)){
     5            return $this->$key(...$args);
     6        }
     7
     8        $value  = $this->get_arg($key);
     9
     10        if(!$args){
     11            return $value ?? $this->get_arg('vars['.$key.']');
     12        }
     13   
     14        if(is_object($value)){
     15            return count($args) >= 2 ? ($value->{$args[0]} = $args[1]) : $value->{$args[0]};
     16        }
     17
     18        $value  = $args[0];
     19
     20        if(in_array($key, ['script', 'style'])){
     21            $key    .= '[]';
     22        }elseif($key == 'pages[]'){
     23            $slug   = wpjam_pull($value, 'menu_slug');
     24            $parent = wpjam_pull($value, 'parent');
     25            $value  = $parent ? ['subs'=>[$slug=>$value]] : $value+['subs'=>[]];
     26            $slug   = $parent ?: $slug;
     27            $key    = 'pages['.$slug.']';
     28            $value  = array_merge($this->get_arg($key, []), $value, ['subs'=>array_merge($this->get_arg($key.'.subs', []), $value['subs'])]);
     29        }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);
     32        }
     33
     34        if(is_null($value)){
     35            $this->delete_arg($key);
     36        }else{
     37            $this->update_arg($key, $value);
     38        }
     39
     40        return $value;
     41    }
    442
    543    public function prefix(){
     
    947    public function url($path=''){
    1048        return ($this->prefix().'admin_url')($path);
    11     }
    12 
    13     public function add($key, ...$args){
    14         [$name, $value] = count($args) >= 2 ? $args : [null, $args[0]];
    15 
    16         if(in_array($key, ['script', 'style'])){
    17             $this->add_item(null, (is_array($value) ? implode($key == 'script' ? "\n\n" : "\n", $value) : $value), $key);
    18         }elseif(in_array($key, ['action', 'widget'])){
    19             $this->add_item($name, $value, $key.'s');
    20         }elseif($key == 'load'){
    21             $type   = wpjam_pull($value, 'type') ?: array_find(['base'=>'builtin_page', 'plugin_page'=>'plugin_page'], fn($v, $k)=> isset($value[$k]));
    22 
    23             if($type && in_array($type, ['builtin_page', 'plugin_page'])){
    24                 $this->add_item(null, $value, $type.'_load');
    25             }
    26         }elseif($key == 'menu'){
    27             $key    = array_find(['tab_slug'=>'tab', 'menu_slug'=>'page'], fn($v, $k)=> !empty($value[$k]) && !is_numeric($value[$k]));
    28 
    29             if($key == 'page'){
    30                 $slug   = wpjam_pull($value, 'menu_slug');
    31                 $parent = wpjam_pull($value, 'parent');
    32                 $value  = $parent ? ['subs'=>[$slug=>$value]] : $value+['subs'=>[]];
    33                 $slug   = $parent ?: $slug;
    34                 $exists = $this->get_item($slug, 'pages');
    35 
    36                 $this->set_item($slug, ($exists ? array_merge($exists, $value, ['subs'=>array_merge($exists['subs'], $value['subs'])]) : $value), 'pages');
    37             }elseif($key == 'tab'){
    38                 $this->add_item(null, $value, 'tabs');
    39             }
    40         }else{
    41             if(in_array($key, ['query_data', 'query_url'])){
    42                 $exists = $this->get_item($key, 'vars') ?: [];
    43 
    44                 if($key == 'query_data'){
    45                     $value  = $exists+wpjam_map($value, fn($v)=> is_null($v) ? $v : (is_array($v) ? wp_die('query_data 不能为数组') : sanitize_textarea_field($v)));
    46                 }elseif($key == 'query_url'){
    47                     $value  = [...$exists, $value];
    48                 }
    49             }
    50 
    51             $this->set_item($key, $value, 'vars');
    52         }
    53 
    54         return $value;
    55     }
    56 
    57     public function sort($items, $position=false){
    58         return wpjam_sort($items, fn($v)=> ($v['order'] ?? 10) - ($position ? ($v['position'] ?? 10)*1000 : 0));
    59     }
    60 
    61     public function match($load, ...$args){
    62         if(count($args) > 1){
    63             if(!empty($load['plugin_page'])){
    64                 if(is_callable($load['plugin_page'])){
    65                     return $load['plugin_page'](...$args);
    66                 }
    67 
    68                 if(!wpjam_compare($args[0], $load['plugin_page'])){
    69                     return false;
    70                 }
    71             }
    72 
    73             return empty($load['current_tab']) ? !$args[1] : ($args[1] && wpjam_compare($args[1], $load['current_tab']));
    74         }else{
    75             if(!empty($load['screen']) && is_callable($load['screen']) && !$load['screen']($args[0])){
    76                 return false;
    77             }
    78 
    79             if(array_any(['base', 'post_type', 'taxonomy'], fn($k)=> !empty($load[$k]) && !wpjam_compare($args[0]->$k, $load[$k]))){
    80                 return false;
    81             }
    82 
    83             return true;
    84         }
    8549    }
    8650
     
    8852        $ver    = get_plugin_data(WPJAM_BASIC_PLUGIN_FILE)['Version'];
    8953        $static = wpjam_url(dirname(__DIR__), 'relative').'/static';
    90         $vars   = array_map('maybe_closure', $this->get_items('vars'))+array_filter(wpjam_pick($this->screen, ['post_type', 'taxonomy']))+['screen_id'=>$this->screen->id, 'admin_url'=>$GLOBALS['current_admin_url']];
    9154
    9255        wp_enqueue_media($this->screen->base == 'post' ? ['post'=>wpjam_get_admin_post_id()] : []);
     
    9457        wp_enqueue_script('wpjam-script', $static.'/script.js', ['jquery', 'thickbox', 'wp-color-picker', 'jquery-ui-sortable', 'jquery-ui-tabs', 'jquery-ui-draggable', 'jquery-ui-autocomplete'], $ver);
    9558        wp_enqueue_script('wpjam-form', $static.'/form.js', ['wpjam-script'], $ver);
    96         wp_localize_script('wpjam-script', 'wpjam_page_setting', $vars);
     59        wp_localize_script('wpjam-script', 'wpjam_page_setting', array_map('maybe_closure', $this->vars)+['admin_url'=>$GLOBALS['current_admin_url']]+wpjam_pick($this, ['query_data', 'query_url']));
    9760
    9861        if($this->script){
    99             wp_add_inline_script('wpjam-script', "jQuery(function($){".preg_replace('/^/m', "\t", "\n".implode("\n\n", $this->script))."\n});");
     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});");
    10063        }
    10164
    10265        if($this->style){
    103             wp_add_inline_style('wpjam-style', "\n".implode("\n\n", $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))));
    10467        }
    10568    }
     
    10871        if($screen){
    10972            $this->screen   = $screen;
     73            $this->vars     ??= ['screen_id'=>$screen->id]+array_filter(wpjam_pick($screen, ['post_type', 'taxonomy']));
    11074        }
    11175
     
    11377            $type   = 'plugin_page';
    11478            $object = $this->current_tab ?: $this->plugin_page;
    115             $args   = [$this->add($type, $object->menu_slug), ''];
     79            $args   = [$object->menu_slug, ''];
     80
     81            $this->vars += ['plugin_page'=>$args[0]];
    11682
    11783            if($this->current_tab){
    118                 $args[1]    = $this->add('current_tab', $object->tab_slug);
     84                $args[1]    = $object->tab_slug;
     85                $this->vars += ['current_tab'=>$args[1]];
    11986            }else{
    12087                if($screen && str_contains($screen->id, '%')){
     
    13097            $type   = 'builtin_page';
    13198            $args   = [$screen];
    132             $page   = $this->add($type, wpjam_get_post_parameter($type) ?: $GLOBALS['pagenow']);
     99            $page   = $this->$type = wpjam_get_post_parameter($type) ?: $GLOBALS['pagenow'];
    133100            $url    = add_query_arg(array_intersect_key($_REQUEST, array_filter(wpjam_pick($screen, ['taxonomy', 'post_type']))), $this->url($page));
    134101
    135102            $GLOBALS['current_admin_url']   = $url;
     103
     104            $this->vars += [$type=>$page];
    136105
    137106            if(in_array($screen->base, ['edit', 'upload', 'post'])){
     
    148117        do_action('wpjam_'.$type.'_load', ...$args);    // 兼容
    149118
    150         foreach($this->sort(array_filter($this->{$type.'_load'} ?: [], fn($load)=> $this->match($load, ...$args))) as $load){
     119        foreach(wpjam_sort(array_filter($this->get_arg($type.'_load[]'), function($load){
     120            if($this->plugin_page){
     121                $page   = $this->plugin_page->name;
     122                $tab    = ($tab = $this->current_tab) ? $tab->name : '';
     123
     124                if(!empty($load['plugin_page'])){
     125                    if(is_callable($load['plugin_page'])){
     126                        return $load['plugin_page']($page, $tab);
     127                    }
     128
     129                    if(!wpjam_compare($page, $load['plugin_page'])){
     130                        return false;
     131                    }
     132                }
     133
     134                return empty($load['current_tab']) ? !$tab : ($tab && wpjam_compare($tab, $load['current_tab']));
     135            }else{
     136                if(!empty($load['screen']) && is_callable($load['screen']) && !$load['screen']($this->screen)){
     137                    return false;
     138                }
     139
     140                if(array_any(['base', 'post_type', 'taxonomy'], fn($k)=> !empty($load[$k]) && !wpjam_compare($this->screen->$k, $load[$k]))){
     141                    return false;
     142                }
     143
     144                return true;
     145            }
     146        }), 'order', 'desc', 10) as $load){
    151147            if(!empty($load['page_file'])){
    152148                wpjam_map((array)$load['page_file'], fn($file)=> is_file($file) ? include $file : null);
     
    216212
    217213                if(($builtin || $menu->parse($args+['menu_slug'=>$slug])) && $subs){
    218                     $subs   = ($builtin ? [] : [$slug=>wpjam_pull($subs, $slug) ?: $main($args)])+$this->sort($subs, true);
     214                    $subs   = ($builtin ? [] : [$slug=>wpjam_pull($subs, $slug) ?: $main($args)])+wpjam_sort($subs, fn($v)=> ($v['order'] ?? 10) - ($v['position'] ?? 10)*1000);
    219215
    220216                    foreach($subs as $s => $sub){
     
    391387
    392388    public static function get($name){
    393         return (wpjam_admin('actions') ?? [])[$name] ?? null;
     389        return wpjam_admin('page_actions['.$name.']');
    394390    }
    395391
    396392    public static function create($name, $args){
    397         return wpjam_admin('add', 'action', $name, new static(['name'=>$name]+$args));
     393        return wpjam_admin('page_actions['.$name.']', new static(['name'=>$name]+$args));
    398394    }
    399395}
     
    413409
    414410        $widgets    = maybe_callback($this->widgets, $this->name) ?: [];
    415         $widgets    = array_merge($widgets, array_filter(wpjam_admin('widgets') ?: [], [$this, 'is_available']));
     411        $widgets    = array_merge($widgets, array_filter(wpjam_admin('widgets[]'), [$this, 'is_available']));
    416412
    417413        foreach($widgets as $id => $widget){
     
    442438
    443439    public static function add_widget($name, $args){
    444         wpjam_admin('add', 'widget', $name, $args);
     440        wpjam_admin('widgets['.$name.']', $args);
    445441    }
    446442}
     
    501497
    502498        if($object){
    503             $object->page_hook  = $hook;
     499            wpjam_admin('page_hook', $hook);
    504500        }
    505501
     
    528524            }
    529525
    530             wpjam_admin('add', 'query_url', [$this->admin_url, ($this->admin_url = add_query_arg($query_data, $this->admin_url))]);
     526            wpjam_admin('query_url[]', [$this->admin_url, ($this->admin_url = add_query_arg($query_data, $this->admin_url))]);
    531527
    532528            if($this->is_current()){
    533                 wpjam_admin('add', 'query_data', $query_data);
     529                wpjam_admin('query_data', $query_data);
    534530            }
    535531        }
     
    602598            $GLOBALS['current_tab'] = wpjam_get_parameter(...(wp_doing_ajax() ? ['current_tab', [], 'POST'] : ['tab'])) ?: null;
    603599
    604             $tabs   = $this->get_arg('tabs', [], 'callback');
    605             $tabs   += wpjam_array(wpjam_admin('tabs') ?: [], fn($k, $v)=> $this->is_available($v) ? [$v['tab_slug'], $v] : null);
    606             $tabs   = wpjam_array(wpjam_admin('sort', $tabs), function($slug, $tab){
     600            $tabs   = wpjam_array(wpjam_admin('tabs[]'), fn($k, $v)=> $this->is_available($v) ? [$v['tab_slug'], $v] : null);
     601            $tabs   = wpjam_array(wpjam_sort($this->get_arg('tabs', [], 'callback')+$tabs, 'order', 'desc', 10), function($slug, $tab){
    607602                $tab    = new self(['tab_slug'=>$slug, 'admin_url'=>$this->admin_url.'&tab='.$slug]+$tab+['capability'=>$this->capability]);
    608603
     
    626621            $object->chart      ??= $this->chart;
    627622            $object->menu_slug  = $this->menu_slug;
    628             $object->page_hook  = $this->page_hook;
    629623
    630624            if(!wp_doing_ajax()){
     
    637631        }elseif($type){
    638632            $object = $object ?: $this->page_object($type, $name);
    639             $hook   = 'load-'.$this->page_hook;
     633            $hook   = 'load-'.wpjam_admin('page_hook');
    640634
    641635            add_action($hook, fn()=> wpjam_call([$object, 'page_load']));
     
    650644
    651645            if($object->query_args){
    652                 wpjam_admin('add', 'query_data', wpjam_get_data_parameter($object->query_args));
     646                wpjam_admin('query_data', wpjam_get_data_parameter($object->query_args));
    653647            }
    654648        }else{
     
    673667                if($model && class_exists($model)){
    674668                    $cb     = [$model, 'get_'.$type];
    675                     $args   = method_exists(...$cb) ? $cb : $args;
    676                 }elseif(wpjam_is_assoc_array($args)){
     669                    $args   = method_exists(...$cb) ? $cb($this) : $args;
     670                }
     671
     672                if(wpjam_is_assoc_array($args)){
    677673                    $args   += wpjam_pick($this, ['model']);
    678674                }
     
    735731                'capability'=> $this->capability ?: 'manage_options',
    736732                'chart'     => $this->chart,
     733                'sortable'  => $this->sortable,
    737734                'data_type' => 'model',
    738735                'per_page'  => 50
  • wpjam-basic/trunk/includes/class-wpjam-api.php

    r3306852 r3310594  
    5252    }
    5353
    54     public function set($field, $key, $item){
    55         $this->data[$field] = wpjam_set($this->get($field), $key, $item);
    56 
    57         return $item;
    58     }
    59 
    60     public function delete($field, $key){
    61         return wpjam_except($this->get($field), $key);
    62     }
    63 
    64     public function update($field, $data){
    65         return $this->data[$field] = $data;
     54    public function set($field, $key, ...$args){
     55        if($args){
     56            $this->data[$field] = wpjam_set($this->get($field), $key, ...$args);
     57
     58            return $args[0];
     59        }else{
     60            return $this->data[$field] = $key;
     61        }
     62    }
     63
     64    public function delete($field, ...$args){
     65        if($args){
     66            return wpjam_except($this->get($field), $args[0]);
     67        }else{
     68            unset($this->data[$field]);
     69        }
    6670    }
    6771
     
    114118    }
    115119
    116     public function request($vars){
     120    public function filter_query_vars($vars){
     121        return array_merge($vars, ['module', 'action', 'term_id']);
     122    }
     123
     124    public function filter_request($vars){
    117125        if(!empty($vars['module'])){
    118126            remove_action('template_redirect',  'redirect_canonical');
     
    121129        }
    122130
    123         return $vars;
     131        return wpjam_parse_query_vars($vars);
    124132    }
    125133
     
    127135        $wpjam  = self::get_instance();
    128136
    129         wpjam_map($wpjam->activation('empty'), fn($active)=> $active && count($active) >= 2 ? add_action(...$active) : null);
    130 
    131         add_filter('query_vars',    fn($vars)=> array_merge($vars, ['module', 'action', 'term_id']));
    132         add_filter('request',       fn($vars)=> $wpjam->request(wpjam_parse_query_vars($vars)), 11);
     137        array_map(fn($active)=> $active && count($active) >= 2 ? add_action(...$active) : null, $wpjam->activation('empty'));
     138        array_map(fn($filter)=> add_filter($filter, [$wpjam, 'filter_'.$filter], 11), ['query_vars', 'request']);
    133139    }
    134140
    135141    public static function __callStatic($method, $args){
    136         if(str_starts_with($method, 'lazyload_')){
    137             remove_filter(current_filter(), [self::class, $method]);
    138 
    139             wpjam_load_pending(wpjam_remove_prefix($method, 'lazyload_'));
    140 
    141             return array_shift($args);
    142         }
    143 
    144142        $function   = 'wpjam_'.$method;
    145143
     
    205203        $args   = wpjam_get($module, 'args', []);
    206204        $args   = is_array($args) ? $args : wpjam_parse_shortcode_attr(stripslashes_deep($args), 'module');
    207         $parser = wpjam_get($module, 'parser') ?: self::module_parser(wpjam_get($module, 'type'));
     205        $parser = wpjam_get($module, 'callback') ?: self::module_parser(wpjam_get($module, 'type'));
    208206
    209207        return $parser ? ($throw ? wpjam_try($parser, $args) : wpjam_catch($parser, $args)) : $args;
     
    217215        header('X-Content-Type-Options: nosniff');
    218216
    219         rest_send_cors_headers(false); 
     217        rest_send_cors_headers(false);
    220218
    221219        if('OPTIONS' === $_SERVER['REQUEST_METHOD']){
     
    237235
    238236        $name   = substr($action, 4);
    239         $name   = substr($name, str_starts_with($name, '.mag') ? 4 : 0);    // 兼容 
     237        $name   = substr($name, str_starts_with($name, '.mag') ? 4 : 0);    // 兼容
    240238        $name   = str_replace('/', '.', $name);
    241239        $name   = apply_filters('wpjam_json_name', $name);
     
    359357class WPJAM_Platform extends WPJAM_Register{
    360358    public function __get($key){
    361         return $key == 'path' ? (bool)$this->get_items() : parent::__get($key);
     359        return $key == 'path' ? (bool)$this->get_paths() : parent::__get($key);
    362360    }
    363361
     
    379377    public function get_tabbar($page_key=''){
    380378        if(!$page_key){
    381             return wpjam_array($this->get_items(), fn($k)=> ($v = $this->get_tabbar($k)) ? [$k, $v] : null);
     379            return wpjam_array($this->get_paths(), fn($k)=> ($v = $this->get_tabbar($k)) ? [$k, $v] : null);
    382380        }
    383381
    384382        if($tabbar  = $this->get_item($page_key.'.tabbar')){
    385383            return ($tabbar === true ? [] : $tabbar)+['text'=>(string)$this->get_item($page_key.'.title')];
    386         }       
     384        }
    387385    }
    388386
    389387    public function get_page($page_key=''){
    390388        if(!$page_key){
    391             return wpjam_array($this->get_items(), fn($k)=> ($v = $this->get_page($k)) ? [$k, $v] : null);
     389            return wpjam_array($this->get_paths(), fn($k)=> ($v = $this->get_page($k)) ? [$k, $v] : null);
    392390        }
    393391
     
    408406    }
    409407
     408    public function add_path($page_key, $args){
     409        return $this->add_item($page_key, $args);
     410    }
     411
     412    public function delete_path($page_key){
     413        return $this->delete_item($page_key);
     414    }
     415
    410416    public function has_path($page_key, $strict=false){
    411         $item   = $this->get_item($page_key);
    412 
    413         if(!$item || ($strict && isset($item['path']) && $item['path'] === false)){
    414             return false;
    415         }
    416 
    417         return isset($item['path']) || isset($item['callback']);
     417        if($item    = $this->get_item($page_key)){
     418            if($strict && isset($item['path']) && $item['path'] === false){
     419                return false;
     420            }else{
     421                return isset($item['path']) || isset($item['callback']);
     422            }
     423        }
     424
     425        return false;
    418426    }
    419427
     
    423431        }
    424432
    425         $item   = $this->get_item($page_key);
    426 
    427         if(!$item){
    428             return;
    429         }
    430 
    431         $cb     = wpjam_pull($item, 'callback');
    432         $args   = is_array($args) ? array_filter($args, fn($v)=> !is_null($v))+$item : $args;
    433 
    434         if($cb){
    435             if(is_callable($cb)){
    436                 return $cb(...[$args, ...(is_array($args) ? [] : [$item]), $page_key]) ?: '';
    437             }
    438         }else{
    439             $path   = $this->get_path_by_page_type($page_key, $args, $item);
    440 
    441             if($path){
    442                 return $path;
    443             }
    444         }
    445 
    446         return isset($item['path']) ? (string)$item['path'] : null;
    447     }
    448 
    449     public function get_paths($page_key, $args=[]){
    450         $type   = $this->get_item($page_key.'.page_type');
    451         $args   = array_merge($args, wpjam_pick($this->get_item($page_key), [$type]));
    452         $items  = $this->query_items_by_page_type($page_key, $args);
    453 
    454         if($items){
    455             $paths  = array_map(fn($item)=> $this->get_path($page_key, $item['value']), $items);
    456             $paths  = array_filter($paths, fn($path)=> wpjam_if_error($path, null));
    457         }
    458 
    459         return $paths ?? [];
     433        if($item    = $this->get_item($page_key)){
     434            $cb     = wpjam_pull($item, 'callback');
     435            $args   = is_array($args) ? array_filter($args, fn($v)=> !is_null($v))+$item : $args;
     436
     437            if($cb){
     438                if(is_callable($cb)){
     439                    return $cb(...[$args, ...(is_array($args) ? [] : [$item]), $page_key]) ?: '';
     440                }
     441            }else{
     442                if($path    = $this->get_path_by_page_type($page_key, $args, $item)){
     443                    return $path;
     444                }
     445            }
     446
     447            return isset($item['path']) ? (string)$item['path'] : null;
     448        }   
     449    }
     450
     451    public function get_paths($page_key=null, $args=[]){
     452        if($page_key){
     453            $type   = $this->get_item($page_key.'.page_type');
     454            $args   = array_merge($args, wpjam_pick($this->get_item($page_key), [$type]));
     455            $items  = $this->query_items_by_page_type($page_key, $args);
     456
     457            if($items){
     458                $paths  = array_map(fn($item)=> $this->get_path($page_key, $item['value']), $items);
     459                $paths  = array_filter($paths, fn($path)=> wpjam_if_error($path, null));
     460            }
     461
     462            return $paths ?? [];
     463        }
     464
     465        return $this->get_items();
    460466    }
    461467
     
    635641}
    636642
    637 class WPJAM_Path extends WPJAM_Register{
    638     public function __get($key){
    639         if(in_array($key, ['platform', 'path_type'])){
    640             return array_keys($this->get_items());
    641         }
    642 
    643         return parent::__get($key);
    644     }
    645 
     643class WPJAM_Path extends WPJAM_Args{
    646644    public function get_fields($platforms){
    647645        return array_reduce($platforms, fn($fields, $pf)=> array_merge($fields, $pf->get_fields($this->name)), []);
    648646    }
    649647
    650     public function add_platform($pf, $args){
    651         $platform   = WPJAM_Platform::get($pf);
    652 
    653         if(!$platform){
    654             return;
    655         }
    656 
    657         $page_type  = wpjam_get($args, 'page_type');
    658 
    659         if($page_type && in_array($page_type, ['post_type', 'taxonomy']) && empty($args[$page_type])){
    660             $args[$page_type]   = $this->name;
    661         }
    662 
    663         if(isset($args['group']) && is_array($args['group'])){
    664             $group  = wpjam_pull($args, 'group');
    665 
    666             if(isset($group['key'], $group['title'])){
    667                 self::group($group['key'], ['title'=>$group['title'], 'options'=>[]]);
    668 
    669                 $args['group']  = $group['key'];
    670             }
    671         }
    672 
    673         $args   = array_merge($args, ['platform'=>$pf, 'path_type'=>$pf]);
    674 
    675         $this->update_args($args, false)->add_item($pf, $args);
    676 
    677         $platform->add_item($this->name, $args);
     648    public function add_platform(...$args){
     649        [$pf, $args]    = count($args) >= 2 ? $args : [array_find(wpjam_pull($args[0], ['platform', 'path_type']), fn($v)=> $v), $args[0]];
     650
     651        if(is_array($pf)){
     652            array_map(fn($v)=> $this->add_platform($v, $args), $pf);
     653        }else{
     654            $page_type  = wpjam_get($args, 'page_type');
     655            $group      = wpjam_get($args, 'group');
     656
     657            if(in_array($page_type, ['post_type', 'taxonomy'])){
     658                $args[$page_type]   ??= $this->name;
     659            }
     660
     661            if(is_array($group)){
     662                if(isset($group['key'], $group['title'])){
     663                    self::group($group['key'], ['title'=>$group['title'], 'options'=>[]]);
     664
     665                    $args['group']  = $group['key'];
     666                }else{
     667                    unset($args['group']);
     668                }
     669            }
     670
     671            $this->update_arg('platforms[]', $pf)->update_args($args, false);
     672
     673            if($platform = WPJAM_Platform::get($pf)){
     674                $platform->add_path($this->name, array_merge($args, ['platform'=>$pf, 'path_type'=>$pf]));
     675            }
     676        }
     677
     678        return $this;
     679    }
     680
     681    public function remove_platform($pf){
     682        if(!$pf){
     683            array_map([$this, 'remove_platform'], $this->platform);
     684        }else{
     685            $this->delete_arg('platforms[]', $pf);
     686
     687            if($platform = WPJAM_Platform::get($pf)){
     688                $platform->delete_path($this->name);
     689            }
     690        }
    678691    }
    679692
     
    683696
    684697    public static function create($name, ...$args){
    685         $object = (self::get($name)) ?: self::register($name, []);
    686         $args   = count($args) == 2 ? ['platform'=>$args[0]]+$args[1] : $args[0];
    687         $args   = wp_is_numeric_array($args) ? $args : [$args];
    688 
    689         foreach($args as $_args){
    690             foreach(wpjam_pick($_args, ['platform', 'path_type']) as $value){
    691                 wpjam_map(wpjam_array($value), fn($pf)=> $object->add_platform($pf, $_args));
    692             }
    693         }
    694 
    695         return $object;
     698        $object = self::get($name) ?: wpjam('add', 'path', new static(['name'=>$name]));
     699
     700        return $args ? $object->add_platform(...$args) : $object;
    696701    }
    697702
    698703    public static function remove($name, $pf=''){
    699         if($pf){
    700             if($object = self::get($name)){
    701                 $object->delete_item($pf);
    702             }
    703 
    704             if($platform = WPJAM_Platform::get($pf)){
    705                 $platform->delete_item($name);
    706             }
    707         }else{
    708             self::unregister($name);
    709 
    710             wpjam_map(WPJAM_Platform::get_registereds(), fn($pf)=> $pf->delete_item($name));
    711         }
     704        if($object = self::get($name)){
     705            $object->remove_platform($pf);
     706
     707            return $pf ? $object : wpjam('delete', 'path', $name);
     708        }
     709    }
     710
     711    public static function get_by($args=[]){
     712        $type   = wpjam_pull($args, 'path_type');
     713        $args   += ($type ? ['platform'=>$type] : []) + $args;
     714        $items  = wpjam('get', 'path');
     715
     716        return wpjam_filter($items, $args, 'AND');
     717    }
     718
     719    public static function get($name){
     720        return wpjam('get', 'path', $name);
    712721    }
    713722}
    714723
     724/**
     725* @config model=0
     726**/
     727#[config(model:false)]
    715728class WPJAM_Data_Type extends WPJAM_Register{
    716729    public function __call($method, $args){
     
    10571070
    10581071        if($code && ($code < 200 || $code >= 300)){
    1059             return new WP_Error($code, '远程服务器错误:'.$code.' - '.$response['response']['message']);
     1072            return new WP_Error($code, '远程服务器错误:'.$code.' - '.$response['response']['message'].'-'.var_export($response['body'], true));
    10601073        }
    10611074
     
    11671180                }
    11681181            }
    1169        
     1182
    11701183            return $types;
    11711184        }
     
    11821195
    11831196            $upload = wp_upload_bits($name, null, $bits);
    1184         }else{ 
     1197        }else{
    11851198            $args   += ['test_form'=>false];
    11861199            $upload = is_array($name) ? wp_handle_sideload($name, $args) : wp_handle_upload($_FILES[$name], $args);
     
    13141327                }
    13151328            }
    1316        
     1329
    13171330            $size   = [
    13181331                'crop'      => $crop ?? ($width && $height),
     
    14841497            $parsed = $item ? $item['errmsg'] : self::parse_message($code, $args);
    14851498
    1486             if($item && !empty($item['modal'])){   
     1499            if($item && !empty($item['modal'])){
    14871500                $data   = array_merge((is_array($data) ? $data : []), ['modal'=>$item['modal']]);
    14881501            }
  • wpjam-basic/trunk/includes/class-wpjam-args.php

    r3305886 r3310594  
    339339    }
    340340
    341     public function delete_arg($key){
    342         $this->args = wpjam_except($this->get_args(), $key);
     341    public function delete_arg($key, ...$args){
     342        if($args && is_string($key) && str_ends_with($key, '[]')){
     343            $key    = substr($key, 0, -2);
     344            $items  = $this->get_arg($key);
     345
     346            if(is_array($items)){
     347                $this->update_arg($key, array_diff($items, $args));
     348            }
     349        }else{
     350            $this->args = wpjam_except($this->get_args(), $key);
     351        }
    343352
    344353        return $this;
     
    510519        if($group || $called){
    511520            $name   = strtolower($group ?: $called);
    512             $group  = WPJAM_Register_Group::get_instance($name);
    513 
    514             if(!$group){
    515                 $group  = $called && method_exists($called, 'get_defaults') ? ['defaults'=>static::get_defaults()] : [];
    516                 $group  = WPJAM_Register_Group::get_instance($name, compact('called', 'name')+$group);
    517             }
     521            $group  = WPJAM_Register_Group::get_instance($name) ?: WPJAM_Register_Group::get_instance($name, compact('called', 'name')+[
     522                'defaults'=> $called && method_exists($called, 'get_defaults') ? static::get_defaults() : []
     523            ]);
    518524
    519525            return [$group, $method](...$args);
     
    576582
    577583class WPJAM_Register_Group extends WPJAM_Args{
    578     use WPJAM_Items_Trait;
    579 
    580584    public function get_objects($args=[], $operator='AND'){
    581         wpjam_map(($this->pull('defaults') ?: []), [$this, 'add_object']);
    582 
    583         $objects    = $args ? wpjam_filter($this->get_items(), $args, $operator) : $this->get_items();
    584 
    585         if($orderby = $this->get_config('orderby')){
    586             $orderby    = $orderby === true ? 'order' : $orderby;
    587             $order      = $this->get_config('order') ?? 'DESC';
    588 
    589             return wpjam_sort($objects, fn($v)=> ($v->$orderby ?? 10), $order);
    590         }
    591 
    592         return $objects;
     585        wpjam_map($this->pull('defaults'), [$this, 'add_object']);
     586
     587        $objects    = wpjam_filter($this->get_arg('objects[]'), $args, $operator);
     588        $orderby    = $this->get_config('orderby');
     589
     590        return $orderby ? wpjam_sort($objects, ($orderby === true ? 'order' : $orderby), ($this->get_config('order') ?? 'DESC'), 10) : $objects;
    593591    }
    594592
     
    596594        if($by == 'model'){
    597595            if($name && strcasecmp($name, $top) !== 0){
    598                 $object = array_find($this->get_items(), fn($v) => $v->model && is_string($v->model) && strcasecmp($name, $v->model) === 0);
    599 
    600                 return $object ?: $this->get_object(get_parent_class($name), $by, $top);
     596                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);
    601597            }
    602598        }elseif($name){
    603             $object = $this->get_item($name);
    604 
    605             if(!$object && $this->defaults && isset($this->defaults[$name])){
    606                 $object = $this->add_object($name, $this->defaults[$name]);
    607 
    608                 $this->defaults = wpjam_except($this->defaults, $name);
    609             }
    610 
    611             return $object;
     599            return $this->get_arg('objects['.$name.']') ?: (is_null($default = $this->pull('defaults['.$name.']')) ? null : $this->add_object($name, $default));
     600
    612601        }
    613602    }
     
    615604    public function add_object($name, $object){
    616605        $called = $this->called ?: 'WPJAM_Register';
    617         $count  = count($this->get_items());
     606        $count  = count($this->get_arg('objects[]'));
    618607
    619608        if(is_object($name)){
     
    630619        }
    631620
    632         if($this->get_item($name)){
     621        if($this->get_arg('objects['.$name.']')){
    633622            trigger_error($this->name.'「'.$name.'」已经注册。');
    634623        }
     
    642631        }
    643632
    644         $this->add_item($name, $object);
     633        $this->update_arg('objects['.$name.']', $object);
    645634
    646635        if($this->called && ($object->is_active() || $object->active)){
     
    661650
    662651    public function remove_object($name){
    663         return $this->delete_item($name);
     652        return $this->delete_arg('objects['.$name.']');
    664653    }
    665654
     
    671660
    672661    public function filtered($name){
    673         $result = $this->has_item($name, '_filtered');
     662        $result = in_array($name, $this->get_arg('filtered[]'));
    674663
    675664        if(!$result){
    676             $this->add_item(null, $name, '_filtered');
     665            $this->update_arg('filtered[]', $name);
    677666        }
    678667
     
    762751}
    763752
    764 class WPJAM_AJAX extends WPJAM_Register{
    765     public function registered(){
    766         wpjam_map(($this->nopriv ? ['', 'nopriv_'] : ['']), fn($p)=> add_action('wp_ajax_'.$p.$this->name, [$this, 'callback']));
    767     }
    768 
     753class WPJAM_AJAX extends WPJAM_Args{
    769754    public function callback(){
    770755        wpjam_set_die_handler('ajax');
    771756
    772         $result = $this->callback && is_callable($this->callback) ? true : wp_die('invalid_callback');
    773         $data   = array_merge(wpjam_get_data_parameter(), wpjam_except(wpjam_get_post_parameter(), ['action', 'defaults', 'data', '_ajax_nonce']));
    774         $data   = array_merge($data, wpjam_if_error(wpjam_fields($this->fields)->catch('validate', $data, 'parameter'), 'send'));
    775         $result = $this->call_nonce('verify', $data);
    776         $result = wpjam_catch($this->callback, $data, $this->name);
    777         $result = $result === true ? [] : $result;
    778 
    779         wpjam_send_json($result);
    780     }
    781 
    782     public function get_attr($data=[], $output=null){
    783         $nonce  = $this->call_nonce('create', $data);
    784         $attr   = ['action'=>$this->name, 'data'=>$data]+($nonce ? compact('nonce') : []);
    785 
    786         return $output ? $attr : wpjam_attr($attr, 'data');
    787     }
    788 
    789     protected function call_nonce($action, $data){
    790         if($this->verify !== false){
    791             $data   = array_filter(wp_array_slice_assoc($data, ($this->nonce_keys ?: [])));
    792             $name   = $this->name.($data ? ':'.implode(':', $data) : '');
    793 
    794             if($action == 'create'){
    795                 return wp_create_nonce($name);
    796             }
    797 
    798             return check_ajax_referer($name, false, false) ? true : wp_die('invalid_nonce');   
    799         }
    800     }
    801 
    802     public static function add_hooks(){
    803         if(!is_admin()){
     757        if(!$this->callback || !is_callable($this->callback)){
     758            wp_die('invalid_callback');
     759        }
     760
     761        if($this->admin){
     762            $data   = wpjam_if_error(wpjam_fields($this->fields)->catch('get_parameter', 'POST'), 'send');
     763        }else{
     764            $data   = array_merge(wpjam_get_data_parameter(), wpjam_except(wpjam_get_post_parameter(), ['action', 'defaults', 'data', '_ajax_nonce']));
     765            $data   = array_merge($data, wpjam_if_error(wpjam_fields($this->fields)->catch('validate', $data, 'parameter'), 'send'));
     766            $action = $this->parse_nonce_action($this->name, $data);
     767
     768            if($action && !check_ajax_referer($action, false, false)){
     769                wp_die('invalid_nonce');
     770            }
     771        }   
     772       
     773        return wpjam_send_json(wpjam_catch($this->callback, $data, $this->name));
     774    }
     775
     776    public static function parse_nonce_action($name, $data){
     777        $args = self::get($name);
     778
     779        return wpjam_get($args, 'verify') === false ? '' : array_reduce(wpjam_get($args, 'nonce_keys') ?: [], fn($carry, $k)=> !empty($data[$k]) ? $carry.':'.$data[$k] : $carry, $name);
     780    }
     781
     782    public static function create($name, $args){
     783        if(!is_admin() && !wpjam('get', 'ajax')){
    804784            wpjam_script('wpjam-ajax', [
    805785                'for'       => 'wp, login',
     
    815795            }
    816796        }
     797
     798        if(wp_doing_ajax() && wpjam_get($_REQUEST, 'action') == $name){
     799            $prefix = 'wp_ajax_';
     800
     801            if(!is_user_logged_in()){
     802                if(!wpjam_pull($args, 'nopriv')){
     803                    return;
     804                }
     805
     806                $prefix .= 'nopriv_';
     807            }
     808
     809            add_action($prefix.$name, [new static(['name'=>$name]+$args), 'callback']);
     810        }
     811
     812        return wpjam('add', 'ajax', $name, $args);
     813    }
     814
     815    public static function get($name){
     816        return wpjam('get', 'ajax', $name);
    817817    }
    818818}
    819819
    820820class WPJAM_Data_Processor extends WPJAM_Args{
    821     private $data   = [];
    822 
    823821    public function get_fields($type=''){
    824822        return $type ? array_intersect_key($this->fields, $this->$type ?: []) : $this->fields;
     
    826824
    827825    public function validate(){
    828         $this->sorted   = [];
    829         $this->path     = [];
    830         $this->formulas = wpjam_map($this->formulas, [$this, 'parse_formula']);
     826        $this->formulas = wpjam_map($this->formulas ?: [], [$this, 'parse_formula']);
    831827
    832828        foreach($this->formulas as $key => $formula){
     
    838834        }
    839835
    840         $this->formulas = wpjam_pick($this->formulas, $this->sorted);
     836        $this->formulas = wpjam_pick($this->formulas, $this->sorted ?: []);
    841837
    842838        return true;
    843     }
    844 
    845     protected function invalid($key, $formula, $msg){
    846         return new WP_Error('invalid_formula', '字段'.$this->render_formular($key, $formula).'错误,'.$msg);
    847839    }
    848840
     
    856848        $signs      = ['+', '-', '*', '/', '(', ')', ',', '%'];
    857849        $formula    = preg_split('/\s*(['.preg_quote(implode($signs), '/').'])\s*/', $formula, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
     850        $invalid    = fn($msg)=> new WP_Error('invalid_formula', '字段'.$this->render_formular($formula, $key).'错误,'.$msg);
    858851
    859852        foreach($formula as $t){
    860853            if(is_numeric($t)){
    861854                if(str_ends_with($t, '.')){
    862                     return $this->invalid($key, $formula, '无效数字「'.$t.'」');
     855                    return $invaild('无效数字「'.$t.'」');
    863856                }
    864857            }elseif(str_starts_with($t, '$')){
    865858                if(!in_array(substr($t, 1), array_keys($this->fields))){
    866                     return $this->invalid($key, $formula, '「'.$t.'」未定义');
     859                    return $invaild('「'.$t.'」未定义');
    867860                }
    868861            }elseif($t == '('){
     
    870863            }elseif($t == ')'){
    871864                if(!$depth){
    872                     return $this->invalid($key, $formula, '括号不匹配');
     865                    return $invaild('括号不匹配');
    873866                }
    874867
     
    876869            }else{
    877870                if(!in_array($t, $signs) && !in_array(strtolower($t), $methods)){
    878                     return $this->invalid($key, $formula, '无效的「'.$t.'」');
    879                 }
    880             }
    881         }
    882 
    883         return $depth ? $this->invalid($key, $formula, '括号不匹配') : $formula;
    884     }
    885 
    886     protected function render_formular($key, $formula){
     871                    return $invaild('无效的「'.$t.'」');
     872                }
     873            }
     874        }
     875
     876        return $depth ? $invaild('括号不匹配') : $formula;
     877    }
     878
     879    protected function render_formular($formula, $key){
    887880        return wpjam_get($this->fields[$key], 'title').'「'.$key.'」'.'公式「'.(is_array($formula) ? implode($formula) : $formula).'」';
    888881    }
    889882
    890883    protected function sort_formular($formula, $key){
    891         if(in_array($key, $this->sorted)){
     884        if(in_array($key, $this->sorted ?: [])){
    892885            return;
    893886        }
    894887
    895         if(in_array($key, $this->path)){
    896             wpjam_throw('invalid_formula', '公式嵌套:'.implode(' → ', wpjam_map(array_slice($this->path, array_search($key, $this->path)), fn($k)=> $this->render_formular($k, $formula))));
    897         }
    898 
    899         $this->path = [...$this->path, $key];
    900         $formulas   = is_array($formula[0]) ? array_column($formula, 'formula') : [$formula];
    901 
    902         foreach($formulas as $formula){
     888        if(in_array($key, $this->path ?: [])){
     889            wpjam_throw('invalid_formula', '公式嵌套:'.implode(' → ', wpjam_map(array_slice($this->path, array_search($key, $this->path)), fn($k)=> $this->render_formular($formula, $k))));
     890        }
     891
     892        $this->update_arg('path[]', $key);
     893
     894        foreach((is_array($formula[0]) ? array_column($formula, 'formula') : [$formula]) as $formula){
    903895            foreach($formula as $t){
    904896                if(try_remove_prefix($t, '$') && isset($this->formulas[$t])){
     
    908900        }
    909901
    910         $this->sorted   = [...$this->sorted, $key];
    911         $this->path     = array_diff($this->path, [$key]);
     902        $this->update_arg('sorted[]', $key)->delete_arg('path[]', $key);
    912903    }
    913904
     
    930921    public function process($items, $args=[]){
    931922        $args   = wp_parse_args($args, ['calc'=>true, 'sum'=>true, 'format'=>false, 'orderby'=>'', 'order'=>'', 'filter'=>'']);
    932         $sums   = [];
     923        $sums   = $args['sum'] ? wpjam_array($this->sumable, fn($k, $v)=> $v == 1 ? [$k, 0] : null) : [];
    933924
    934925        foreach($items as $i => $item){
     
    942933            }
    943934
    944             if($args['orderby']){
    945                 $item[$args['orderby']] ??= 0;
     935            if($args['sum']){
     936                $sums   = wpjam_map($sums, fn($v, $k)=> $v+$this->parse_number($item[$k] ?? 0));
     937            }
     938
     939            if($args['format']){
     940                $item   = $this->format($item);
    946941            }
    947942
    948943            $items[$i] = $item;
    949 
    950             if($args['sum']){
    951                 foreach($this->sumable as $k => $v){
    952                     if($r = ($v == 1 && isset($item[$k])) ? $this->parse_number($item[$k]) : 0){
    953                         $sums[$k]   = ($sums[$k] ?? 0)+$r;
    954                     }
    955                 }
    956             }
    957944        }
    958945
    959946        if($args['orderby']){
    960             $items  = wpjam_sort($items, [$args['orderby'] => $args['order']]);
    961         }
    962 
    963         if($sums){
    964             $items  = wpjam_add_at($items, 0, null, $this->calc($sums, ['sum'=>true])+(is_array($args['sum']) ? $args['sum'] : []));
    965         }
    966 
    967         if($args['format']){
    968             foreach($items as $i => $item){
    969                 foreach($this->formats as $k => $v){
    970                     if(isset($item[$k]) && is_numeric($item[$k])){
    971                         $item[$k]   = wpjam_format($item[$k], ...$v);
    972                     }
    973                 }
    974 
    975                 $items[$i] = $item;
    976             }
     947            $items  = wpjam_sort($items, $args['orderby'], $args['order']);
     948        }
     949
     950        if($args['sum']){
     951            $sums   = $this->calc($sums, ['sum'=>true])+(is_array($args['sum']) ? $args['sum'] : []);
     952            $sums   = $args['format'] ? $this->format($sums) : $sums;
     953            $items  = array_merge([$sums], $items);
    977954        }
    978955
     
    985962        }
    986963
    987         if(!isset($this->sorted)){
     964        if(!is_array($this->sorted)){
    988965            $this->validate();
    989966        }
     
    10671044    }
    10681045
    1069     public function sum($items, $calc=false){
    1070         if(($this->sumable || $calc) && $items){
    1071             return $this->calc($this->process($items, ['sum'=>true, 'calc'=>$calc])[0], ['sum'=>true]);
    1072         }
    1073     }
    1074 
    1075     public function accumulate($item=null, $group=''){
    1076         if($item){
     1046    public function sum($items, $args=[]){
     1047        if($this->sumable && $items){
     1048            if($field   = wpjam_pull($args, 'field')){
     1049                return wpjam_map(wpjam_group($items, $field), fn($items, $field)=> array_merge(array_values($items)[0], $this->sum($items, $args)));
     1050            }else{
     1051                return $this->calc($this->process($items, $args+['sum'=>true])[0], ['sum'=>true]);
     1052            }
     1053        }
     1054
     1055        return [];
     1056    }
     1057
     1058    public function accumulate($results, $items, $group=''){
     1059        foreach($items as $item){
    10771060            $item   = $this->calc($item);
    10781061            $value  = $group ? ($item[$group] ?? '') : '__';
    10791062            $keys   = $this->sumable ? array_keys(array_filter($this->sumable, fn($v)=> $v == 1)) : [];
    10801063
    1081             $this->data[$group][$value] ??= array_merge($item, array_fill_keys($keys, 0));
     1064            $results[$value]    ??= array_merge($item, array_fill_keys($keys, 0));
    10821065
    10831066            foreach($keys as $k){
    10841067                if($r = isset($item[$k]) ? $this->parse_number($item[$k]) : 0){
    1085                     $this->data[$group][$value][$k] += $r;
    1086                 }
    1087             }
    1088 
    1089             return $this->data[$group];
    1090         }
    1091 
    1092         $items  = wpjam_pull($this->data, $group) ?: [];
    1093         $items  = array_map(fn($item)=> $this->calc($item, ['sum'=>true]), $items);
    1094 
    1095         return $group ? $items : ($items['__'] ?? []);
     1068                    $results[$value][$k]    += $r;
     1069                }
     1070            }
     1071        }
     1072
     1073        return $group ? $results : $results[$value];
     1074    }
     1075
     1076    public function format($item){
     1077        foreach($this->formats ?: [] as $k => $v){
     1078            if(isset($item[$k]) && is_numeric($item[$k])){
     1079                $item[$k]   = wpjam_format($item[$k], ...$v);
     1080            }
     1081        }
     1082
     1083        return $item;
    10961084    }
    10971085
  • wpjam-basic/trunk/includes/class-wpjam-field.php

    r3305886 r3310594  
    116116    protected function render_data($args){
    117117        return implode(wpjam_map($args, function($v, $k){
    118             if(is_null($v) || $v === false){
     118            if(is_null($v) || $v === false || $k == '__data'){
    119119                return '';
    120120            }
     
    714714    public function wrap($tag='', $args=[]){
    715715        if(is_object($tag)){
    716             $wrap   = $this->wrap_tag ?: (($this->is('fieldset') && !$this->group && !$args) ? '' : 'div');
    717 
    718             $tag->wrap($wrap, $args)->add_class($this->group ? 'field-group' : '');
     716            $group  = $this->group && !$this->is('fields');
     717            $wrap   = $this->wrap_tag ?: (($this->is('fieldset') && !$group && !$args) ? '' : 'div');
     718
     719            $tag->wrap($wrap, $args)->add_class($group ? 'field-group' : '');
    719720
    720721            if($wrap == 'fieldset' && $this->title){
     
    749750        }
    750751
    751         foreach(array_filter(wpjam_pick($this, ['before', 'after'])) as $k => $v){
    752             $action = $field->is('div') ? ($k == 'before' ? 'prepend' : 'append') : $k;
    753 
    754             $field->$action($k == 'before' ? $v.'&nbsp;' : '&nbsp;'.$v);
     752        foreach(['before', 'after'] as $k){
     753            if($v = $this->$k){
     754                $field->$k(($field->is('div') || $this->is('textarea,editor') ? 'p' : 'span'), [$k], $v);
     755            }
    755756        }
    756757
    757758        if($this->is('fieldset')){
    758             $_args  = array_filter(wpjam_pick($this, ['class', 'style'])+['data'=>$this->data()]);
    759             $_args  = $_args ? wpjam_set($_args, 'data.key', $this->key) : [];
    760 
    761             $this->wrap($field, $_args);
     759            $this->wrap($field, (($attr = array_filter(wpjam_pick($this, ['class', 'style'])+['data'=>$this->data()])) ? wpjam_set($attr, 'data.key', $this->key) : []));
    762760
    763761            $wrap->after("\n");
     
    770768        $class  = [$this->wrap_class, wpjam_get($args, 'wrap_class'), $this->disabled, $this->readonly, ($this->is('hidden') ? 'hidden' : '')];
    771769        $title  = $this->title ? wpjam_tag('label', $label, $this->title) : '';
    772         $desc   = $this->description ?: '';
    773 
    774         if($desc){
    775             if(is_array($desc)){
    776                 $attr   = $desc[1] ?? [];
    777                 $attr   = (isset($attr['show_if']) ? ['data-show_if'=>$this->parse_show_if(wpjam_pull($attr, 'show_if'))] : []) + $attr;
    778                 $desc   = $desc[0];
    779             }
    780 
    781             $desc   = wpjam_tag('p', ($attr ?? [])+['class'=>'description'], $desc);
    782         }
    783 
    784         $field->after($desc);
     770        $desc   = (array)$this->description;
     771
     772        if($desc && $desc[0]){
     773            [$desc, $attr]  = $desc+['', []];
     774
     775            $field->after('p', ['class'=>'description', 'data-show_if'=>$this->parse_show_if(wpjam_pull($attr, 'show_if'))]+$attr, $desc);
     776        }
    785777
    786778        $show_if    = $this->parse_show_if();
     
    788780        if($creator && !$creator->is('fields')){
    789781            if($creator->wrap_tag == 'fieldset'){
    790                 if($title || $desc || ($show_if && ($this->is('fields') || !is_null($field->data('query_title'))))){
     782                if($title || ($show_if && ($this->is('fields') || !is_null($field->data('query_title'))))){
    791783                    $field->before($title ? ['<br />', $title] : null)->wrap('div', ['inline']);
    792784                }
     
    13871379            }
    13881380
    1389             $parsed = array_merge($parsed, $subs ? self::parse($subs, $args) : []);
     1381            $parsed = array_merge($parsed, !empty($subs) ? self::parse($subs, $args) : []);
    13901382        }
    13911383
  • wpjam-basic/trunk/includes/class-wpjam-list-table.php

    r3306852 r3310594  
    7474        }
    7575
    76         wpjam_admin('add', 'style', array_filter($style));
    77         wpjam_admin('add', 'list_table', fn()=> $this->get_setting());
    78         wpjam_admin('add', 'page_title_action', fn()=> $this->get_action('add', ['class'=>'page-title-action']) ?: '');
     76        wpjam_admin('style', array_filter($style));
     77        wpjam_admin('vars[list_table]', fn()=> $this->get_setting());
     78        wpjam_admin('vars[page_title_action]', fn()=> $this->get_action('add', ['class'=>'page-title-action']) ?: '');
    7979
    8080        add_filter('views_'.$screen->id, [$this, 'filter_views']);
     
    197197
    198198            if($method == 'columns'){
    199                 return wpjam_except($args ? wpjam_add_at($args[0], -1, $value) : $value, $this->call_type('column', 'removed'));
     199                return wpjam_except(($args ? wpjam_add_at($args[0], -1, $value) : $value), WPJAM_List_Table_Column::removed());
    200200            }elseif($method == 'row_actions'){
    201201                if($this->layout != 'calendar'){
     
    205205
    206206                $value  = wpjam_except($value, ($this->next_actions ?: []));
    207                 $value  = wpjam_except($args[0]+$this->get_actions($value, $args[1]), $this->call_type('action', 'removed'));
     207                $value  = wpjam_except($args[0]+$this->get_actions($value, $args[1]), WPJAM_List_Table_Action::removed());
    208208                $value  += $this->builtin ? wpjam_pull($value, ['delete', 'trash', 'spam', 'remove', 'view']) : [];
    209209
     
    218218
    219219    protected function get_objects($type='action'){
    220         self::call_type($type, 'registers', $type == 'column' ? $this->fields : $this->{$type.'s'});
    221 
    222220        $args   = WPJAM_Data_Type::prepare($this);
     221        $class  = 'WPJAM_List_Table_'.$type;
     222
     223        [$class, 'registers']($type == 'column' ? $this->fields : $this->{$type.'s'});
    223224
    224225        if($type == 'action'){
     
    234235                    'up'    => ['page_title'=>'向上移动',   'dashicon'=>'arrow-up-alt'],
    235236                    'down'  => ['page_title'=>'向下移动',   'dashicon'=>'arrow-down-alt'],
    236                 ], fn($v, $k)=> self::call_type($type, 'register', $k, $action+$v+['direct'=>true]));
     237                ], fn($v, $k)=> [$class, 'register']($k, $action+$v+['direct'=>true]));
    237238
    238239                $this->sortable = $sortable;
     
    244245        }
    245246
    246         return $this->objects[$type] = self::call_type($type, 'get_registereds', wpjam_map($args, fn($v)=> ['value'=>$v, 'if_null'=>true, 'callable'=>true]));
     247        return $this->objects[$type] = [$class, 'get_registereds']($args);
    247248    }
    248249
     
    654655        return wpjam_get_request_parameter('list_action') ?? parent::current_action();
    655656    }
    656 
    657     public static function call_type($type, $method, ...$args){
     657}
     658
     659class WPJAM_List_Table_Component extends WPJAM_Args{
     660    public static function __callStatic($method, $args){
     661        $type   = strtolower(wpjam_at(explode('_', get_called_class(), 2), -1));
     662
    658663        if($method == 'removed'){
    659             $opt    = 'remove_'.$type.'s';
    660             $option = get_screen_option($opt) ?: [];
    661 
    662             return $args ? add_screen_option($opt, [...$option, ...$args]) : $option;
    663         }
    664 
    665         $class  = 'WPJAM_List_Table_'.$type;
    666 
    667         if(in_array($method, ['register', 'unregister'])){
    668             $name       = $args[0];
    669             $args[0]    .= WPJAM_Data_Type::prepare($args[1], 'key');
     664            return wpjam_admin('removed['.$type.'][]', ...$args);
     665        }elseif($method == 'get_registereds'){
     666            return wpjam_sort(wpjam_filter(wpjam_admin($type.'[]'), wpjam_map($args[0], fn($v)=> ['value'=>$v, 'if_null'=>true, 'callable'=>true])), 'order', 'DESC',  10);
     667        }elseif($method == 'get'){
     668            return $args && $args[0] ? wpjam_admin($type.'['.$args[0].']') : null;
     669        }elseif(in_array($method, ['register', 'unregister'])){
     670            $name   = $args[0];
     671            $args   = $args[1];
     672            $key    = $type.'['.$name.WPJAM_Data_Type::prepare($args, 'key').']';
    670673
    671674            if($method == 'register'){
    672                 if($type == 'action' && !empty($args[1]['overall']) && $args[1]['overall'] !== true){
    673                     self::call_type($type, $method, $name.'_all', array_merge($args[1], ['overall'=>true, 'title'=>$args[1]['overall']]));
    674 
    675                     unset($args[1]['overall']);
    676                 }
    677 
    678                 $args[1]    = new $class($name, $args[1]);
     675                if($type == 'action' && !empty($args['overall']) && $args['overall'] !== true){
     676                    static::$method($name.'_all', array_merge($args, ['overall'=>true, 'title'=>$args['overall']]));
     677
     678                    unset($args['overall']);
     679                }
     680
     681                return wpjam_admin($key, new static(['name'=>$name]+$args));
    679682            }else{
    680                 if(![$class, 'get']($args[0])){
    681                     return self::call_type($type, 'removed', $name);
    682                 }
    683             }
    684         }
    685 
    686         return [$class, $method](...$args);
     683                return wpjam_admin($key) ? wpjam_admin($key, null) : static::removed($name);
     684            }
     685        }
    687686    }
    688687}
    689688
    690 /**
    691 * @config orderby
    692 **/
    693 #[config('orderby')]
    694 class WPJAM_List_Table_Action extends WPJAM_Register{
     689class WPJAM_List_Table_Action extends WPJAM_List_Table_Component{
    695690    public function __get($key){
    696691        $value  = parent::__get($key);
     
    11331128}
    11341129
    1135 /**
    1136 * @config orderby
    1137 **/
    1138 #[config('orderby')]
    1139 class WPJAM_List_Table_Column extends WPJAM_Register{
     1130class WPJAM_List_Table_Column extends WPJAM_List_Table_Component{
    11401131    public function __get($key){
    11411132        $value  = parent::__get($key);
     
    11851176}
    11861177
    1187 /**
    1188 * @config orderby
    1189 **/
    1190 #[config('orderby')]
    1191 class WPJAM_List_Table_View extends WPJAM_Register{
     1178class WPJAM_List_Table_View extends WPJAM_List_Table_Component{
    11921179    public function parse(){
    11931180        if($this->_view){
  • wpjam-basic/trunk/includes/class-wpjam-model.php

    r3305886 r3310594  
    15131513
    15141514            if(in_array($method, ['add', 'insert'])){
    1515                 $item   = wpjam_filter($item, fn($v)=> !is_null($v));
     1515                $item   = array_filter($item, fn($v)=> !is_null($v));
    15161516            }
    15171517        }
  • wpjam-basic/trunk/includes/class-wpjam-post.php

    r3306852 r3310594  
    756756    }
    757757
     758    public function add_field($key, $value){
     759        return $this->update_arg('_fields['.$key.']', $value);
     760    }
     761
     762    public function remove_field($key, $value){
     763        return $this->delete_arg('_fields['.$key.']');
     764    }
     765
    758766    public function get_fields($id=0, $action_key=''){
    759767        if(in_array($action_key, ['add', 'set'])){
     
    792800        }
    793801
    794         foreach($this->get_items('_fields') as $key => $field){
     802        foreach($this->get_arg('_fields[]') as $key => $field){
    795803            if(in_array($action_key, ['add', 'set']) && empty($field['name']) && !property_exists('WP_Post', $key)){
    796804                $field['name']  = 'meta_input['.$key.']';
     
    900908
    901909                if(str_contains($struct, $tag)){
     910                    remove_rewrite_tag('%'.$name.'%');
     911
    902912                    add_rewrite_tag($tag, '([0-9]+)', 'post_type='.$name.'&p=');
    903913
    904                     remove_rewrite_tag('%'.$name.'%');
    905 
    906914                    add_filter('post_type_link', fn($link, $post)=> get_post_type($post) == $name ? str_replace($tag, $post->ID, $link) : $link, 1, 2);
    907                 }else{
    908                     add_permastruct($name, $struct, array_merge($this->rewrite, ['feed'=>$this->rewrite['feeds']]));
    909                 }
    910             }
    911 
    912             if($this->registered_callback){
    913                 wpjam_call($this->registered_callback, $name, $object);
    914             }
     915                }
     916
     917                add_permastruct($name, $struct, array_merge($this->rewrite, ['feed'=>$this->rewrite['feeds']]));
     918            }
     919
     920            wpjam_call($this->registered_callback, $name, $object);
    915921        }, 10, 2);
    916922
  • wpjam-basic/trunk/includes/class-wpjam-setting.php

    r3306852 r3310594  
    164164
    165165        if($filter){
    166             foreach(wpjam_sort(self::get_by(['type'=>'section', 'name'=>$this->name]), fn($v)=> $v['order'] ?? 10) as $object){
     166            foreach(wpjam_sort(self::get_by(['type'=>'section', 'name'=>$this->name]), 'order', 'desc', 10) as $object){
    167167                foreach(($object->get_arg('sections') ?: []) as $id => $section){
    168168                    $section    = $this->parse_section($section, $id);
     
    214214
    215215        $cb     = 'wpjam_get_'.($site ? 'site_' : '').'option';
    216         $data   = $cb($this->option);
     216        $data   = $cb($this->name);
    217217
    218218        return $data ?: [];
     
    257257
    258258    public function prepare(){
    259         return $this->get_fields(true, 'object')->prepare();
     259        return wpjam_get($this->get_fields(true, 'object')->prepare(), $this->option_type == 'array' ? null : $this->name);
    260260    }
    261261
     
    888888
    889889    public function prepare($id=null){
    890         if($this->callback){
    891             return [];
    892         }
    893 
    894         return $this->get_fields($id)->prepare();
     890        return $this->callback ? [] : $this->get_fields($id)->prepare();
    895891    }
    896892
  • wpjam-basic/trunk/includes/class-wpjam-term.php

    r3305886 r3310594  
    573573    }
    574574
     575    public function add_field($key, $value){
     576        return $this->update_arg('_fields['.$key.']', $value);
     577    }
     578
     579    public function remove_field($key, $value){
     580        return $this->delete_arg('_fields['.$key.']');
     581    }
     582
    575583    public function get_fields($id=0, $action_key=''){
    576584        $fields = [];
     
    624632                'description'   => $this->banner_size ? '尺寸:'.$this->banner_size : '',
    625633                'show_if'       => [
    626                     'key'       => 'parent', 
     634                    'key'       => 'parent',
    627635                    'value'     => -1,
    628636                    'external'  => $action_key != 'set'
     
    631639        }
    632640
    633         return array_merge($fields, $this->get_items('_fields'));
     641        return array_merge($fields, $this->get_arg('_fields[]'));
    634642    }
    635643
     
    658666
    659667    public function add_support($feature, $value=true){
    660         return $this->add_item($feature, $value, 'supports');
     668        return $this->update_arg('supports.'.$feature, $value);
    661669    }
    662670
    663671    public function remove_support($feature){
    664         return $this->delete_item($feature, 'supports');
     672        return $this->delete_arg('supports.'.$feature);
    665673    }
    666674
    667675    public function supports($feature){
    668         return (bool)$this->get_item($feature, 'supports');
     676        return (bool)$this->get_arg('supports.'.$feature);
    669677    }
    670678
     
    784792            }
    785793
    786             if($this->registered_callback){
    787                 wpjam_call($this->registered_callback, $name, $object_type, $args);
    788             }
     794            wpjam_call($this->registered_callback, $name, $object_type, $args);
    789795        }, 10, 3);
    790796
    791797        wpjam_init(function(){
    792798            if($this->_jam){
    793            
     799
    794800                if(is_admin() && $this->show_ui){
    795801                    add_filter('taxonomy_labels_'.$this->name,  [$this, 'filter_labels']);
     
    808814        $no_base    = ($structure && $request && !isset($vars['module'])) ? array_filter(get_taxonomies(), fn($tax)=> wpjam_get_taxonomy_setting($tax, 'permastruct') == '%'.$tax.'%') : [];
    809815
    810         if($no_base){
    811             if($GLOBALS['wp_rewrite']->use_verbose_page_rules){
    812                 if(preg_match("#(.?.+?)/page/?([0-9]{1,})/?$#", $request, $matches)){
    813                     $request    = $matches[1];
    814                     $paged      = $matches[2];
    815                 }
    816 
    817                 if(!empty($vars['error']) && $vars['error'] == '404'){
    818                     $key    = 'error';
    819                 }elseif(str_starts_with($structure, '/%postname%')){
    820                     if(!empty($vars['name'])){
    821                         $key    = 'name';
    822                     }
    823                 }elseif(!str_contains($request, '/')){
    824                     $k  = array_find(['author', 'category'], fn($k)=> str_starts_with($structure, '/%'.$k.'%'));
    825 
    826                     if($k && !str_starts_with($request, $k.'/') && !empty($vars[$k.'_name'])){
    827                         $key    = [$k.'_name', 'name'];
    828                     }
    829                 }
    830             }elseif(!empty($vars['pagename']) && !isset($_GET['page_id']) && !isset($_GET['pagename'])){
    831                 $key    = 'pagename';
    832             }
    833 
    834             if(!empty($key)){
    835                 foreach($no_base as $tax){
    836                     $name   = is_taxonomy_hierarchical($tax) ? wp_basename($request) : $request;
    837 
    838                     if(array_find(wpjam_get_all_terms($tax), fn($term)=> $term->slug == $name)){
    839                         $vars   = wpjam_except($vars, $key);
    840 
    841                         if($tax == 'category'){
    842                             $vars['category_name']  = $name;
    843                         }else{
    844                             $vars['taxonomy']   = $tax;
    845                             $vars['term']       = $name;
    846                         }
    847 
    848                         if(!empty($paged)){
    849                             $vars['paged']  = $paged;
    850                         }
    851 
    852                         break;
    853                     }
    854                 }               
     816        if(!$no_base){
     817            return $vars;
     818        }
     819
     820        if(preg_match("#(.?.+?)/page/?([0-9]{1,})/?$#", $request, $matches)){
     821            $request    = $matches[1];
     822            $paged      = $matches[2];
     823        }
     824
     825        if($GLOBALS['wp_rewrite']->use_verbose_page_rules){
     826            if(!empty($vars['error']) && $vars['error'] == '404'){
     827                $key    = 'error';
     828            }elseif(str_starts_with($structure, '/%postname%')){
     829                if(!empty($vars['name'])){
     830                    $key    = 'name';
     831                }
     832            }elseif(!str_contains($request, '/')){
     833                $k  = array_find(['author', 'category'], fn($k)=> str_starts_with($structure, '/%'.$k.'%'));
     834
     835                if($k && !str_starts_with($request, $k.'/') && !empty($vars[$k.'_name'])){
     836                    $key    = [$k.'_name', 'name'];
     837                }
     838            }
     839        }elseif(!empty($vars['pagename']) && !isset($_GET['page_id']) && !isset($_GET['pagename'])){
     840            $key    = 'pagename';
     841        }
     842
     843        if(empty($key)){
     844            return $vars;
     845        }
     846
     847        foreach($no_base as $tax){
     848            $name   = is_taxonomy_hierarchical($tax) ? wp_basename($request) : $request;
     849
     850            if(array_find(wpjam_get_all_terms($tax), fn($term)=> $term->slug == $name)){
     851                $vars   = wpjam_except($vars, $key);
     852
     853                if($tax == 'category'){
     854                    $vars['category_name']  = $name;
     855                }else{
     856                    $vars['taxonomy']   = $tax;
     857                    $vars['term']       = $name;
     858                }
     859
     860                if(!empty($paged)){
     861                    $vars['paged']  = $paged;
     862                }
     863
     864                break;
    855865            }
    856866        }
  • wpjam-basic/trunk/public/wpjam-compat.php

    r3305886 r3310594  
    8787    function array_find_index($arr, $callback){
    8888        return wpjam_find($arr, $callback, 'index');
     89    }
     90}
     91
     92if(!function_exists('filter_deep')){
     93    function filter_deep($arr, $data){
     94        return wpjam_filter($arr, $callback, true);
    8995    }
    9096}
     
    305311}
    306312
     313function wpjam_localize_script($handle, $name, $l10n ){
     314    wp_localize_script($handle, $name, ['l10n_print_after' => $name.' = '.wpjam_json_encode($l10n)]);
     315}
     316
    307317function wpjam_wrap_tag($text, $tag='', $attr=[]){
    308318    return wpjam_tag($tag, $attr, $text);
     
    353363
    354364function wpjam_get_admin_prefix(){
    355     return wpjam_admin()->prefix;
     365    return wpjam_admin()->prefix();
    356366}
    357367
     
    369379
    370380function wpjam_add_admin_inline_script($data){
    371     wpjam_admin('add', 'script', $data);
     381    wpjam_admin('script', $data);
    372382}
    373383
    374384function wpjam_add_admin_inline_style($data){
    375     wpjam_admin('add', 'style', $data);
     385    wpjam_admin('style', $data);
    376386}
    377387
     
    453463
    454464function wpjam_register_plugin_page_tab($name, $args){
    455     return wpjam_admin('add', 'menu', array_merge($args, ['tab_slug'=>$name]));
     465    return wpjam_add_menu_page(['tab_slug'=>$name]+$args);
    456466}
    457467
  • wpjam-basic/trunk/public/wpjam-functions.php

    r3306852 r3310594  
    3737
    3838function wpjam_add_item($group, $key, ...$args){
    39     if(is_object($group)){
    40         if($key && is_array($key)){
    41             return wpjam_map($key, fn($v, $k)=> wpjam_add_item($group, $k, $v, ...$args));
    42         }
    43 
    44         $result = $group->add_item($key, ...$args);
    45 
    46         return is_wp_error($result) ? $result : $args[0];
    47     }
    48 
    4939    return wpjam('add', $group, $key, ...$args);
    5040}
     
    111101    }
    112102
    113     return $object ? array_keys(wp_list_filter($object->get_items(), (is_array($args) ? $args : []), $operator)) : [];
     103    return $object ? array_keys(wpjam_filter($object->get_paths(), (is_array($args) ? $args : []), $operator)) : [];
    114104}
    115105
     
    336326}
    337327
    338 function wpjam_add_post_type_field($post_type, ...$args){
    339     if(($object = WPJAM_Post_Type::get($post_type)) && $args && $args[0]){
    340         wpjam_add_item($object, ...[...$args, '_fields']);
     328function wpjam_add_post_type_field($post_type, $key, ...$args){
     329    if($object = WPJAM_Post_Type::get($post_type)){
     330        foreach((is_array($key) ? $key : [$key => $args[0]]) as $k => $v){
     331            $object->add_field($k, $v);
     332        }
    341333    }
    342334}
    343335
    344336function wpjam_remove_post_type_field($post_type, $key){
    345     if(($object = WPJAM_Post_Type::get($post_type)) && $key){
    346         $object->delete_item($key, '_fields');
     337    if($object = WPJAM_Post_Type::get($post_type)){
     338        $object->remove_fields($key);
    347339    }
    348340}
     
    470462}
    471463
     464function wpjam_pagenavi($total=0, $echo=true){
     465    $result = '<div class="pagenavi">'.paginate_links(array_filter([
     466        'prev_text' => '&laquo;',
     467        'next_text' => '&raquo;',
     468        'total'     => $total
     469    ])).'</div>';
     470
     471    return $echo ? wpjam_echo($result) : $result;
     472}
     473
    472474// $number
    473475// $post_id, $args
     
    497499}
    498500
    499 function wpjam_add_taxonomy_field($taxonomy, ...$args){
    500     if(($object = WPJAM_Taxonomy::get($taxonomy)) && $args && $args[0]){
    501         wpjam_add_item($object, ...[...$args, '_fields']);
     501function wpjam_add_taxonomy_field($taxonomy, $key, ...$args){
     502    if($object = WPJAM_Taxonomy::get($taxonomy)){
     503        foreach((is_array($key) ? $key : [$key => $args[0]]) as $k => $v){
     504            $object->add_field($k, $v);
     505        }
    502506    }
    503507}
    504508
    505509function wpjam_remove_taxonomy_field($taxonomy, $key){
    506     if(($object = WPJAM_Taxonomy::get($taxonomy)) && $key){
    507         $object->delete_item($key, '_fields');
     510    if($object = WPJAM_Taxonomy::get($taxonomy)){
     511        $object->remove_fields($key);
    508512    }
    509513}
     
    870874// AJAX
    871875function wpjam_register_ajax($name, $args){
    872     return WPJAM_AJAX::register($name, $args);
     876    return WPJAM_AJAX::create($name, $args);
    873877}
    874878
    875879function wpjam_get_ajax_data_attr($name, $data=[], $output=null){
    876     return ($object = WPJAM_AJAX::get($name)) ? $object->get_attr($data, $output) : ($output ? null : []);
     880    if(WPJAM_AJAX::get($name)){
     881        $action = WPJAM_AJAX::parse_nonce_action($name, $data);
     882        $attr   = ['action'=>$name, 'data'=>$data, 'nonce'=>($action ? wp_create_nonce($action) : null)];
     883
     884        return $output ? $attr : wpjam_attr($attr, 'data');
     885    }
     886
     887    return $output ? null : [];
    877888}
    878889
  • wpjam-basic/trunk/public/wpjam-route.php

    r3305886 r3310594  
    380380        }
    381381
    382         wpjam('update', 'defaults', $vars);
     382        wpjam('set', 'defaults', $vars);
    383383    }
    384384
     
    397397
    398398function wpjam_ua($name=''){
    399     $vars   = wpjam('get', 'user_agent') ?: wpjam('update', 'user_agent', wpjam_parse_user_agent());
    400 
    401     return $name ? ($vars[$name] ?? null) : $vars;
     399    return $name ? wpjam_get(wpjam_ua(), $name) : (wpjam('get', 'user_agent') ?: wpjam('set', 'user_agent', wpjam_parse_user_agent()));
    402400}
    403401
     
    713711
    714712        $args   = $args[0];
     713        $type   = array_find(['tab_slug'=>'tabs', 'menu_slug'=>'pages'], fn($v, $k)=> !empty($args[$k]) && !is_numeric($args[$k]));
     714
     715        if(!$type){
     716            return;
     717        }
    715718    }else{
    716719        $slug   = $args[0];
    717         $type   = !empty($args[1]['plugin_page']) ? 'tab_slug' : 'menu_slug';
    718         $args   = array_merge($args[1], [$type => $slug]);
     720        $key    = !empty($args[1]['plugin_page']) ? 'tab_slug' : 'menu_slug';
     721        $type   = $key == 'tab_slug' ? 'tabs' : 'pages';
     722        $args   = array_merge($args[1], [$key => $slug]);
    719723
    720724        if(!is_admin() && wpjam_get($args, 'function') == 'option' && (!empty($args['sections']) || !empty($args['fields']))){
     
    740744
    741745    if(is_admin()){
    742         wpjam_admin('add', 'menu', $args);
     746        wpjam_admin($type.'[]', $args);
    743747    }
    744748}
     
    764768        $object = WPJAM_Admin::get_instance();
    765769
    766         if(!$args){
    767             return $object;
    768         }
    769 
    770         $key    = array_shift($args);
    771         $cb     = [$object, $key];
    772 
    773         if(method_exists(...$cb)){
    774             return $cb(...$args);
    775         }
    776 
    777         if(!$args){
    778             return $object->$key ?? wpjam_get($object->vars, $key);
    779         }
    780 
    781         if(!isset($object->$key) || !in_array($key, ['plugin_page', 'current_tab', 'screen'])){
    782             return $object->$key = $args[0];
    783         }
    784 
    785         return count($args) >= 2 ? ($object->$key->{$args[0]} = $args[1]) : $object->$key->{$args[0]};
     770        return $args ? $object->call(...$args) : $object;
    786771    }
    787772
    788773    function wpjam_add_admin_ajax($action, $args=[]){
    789         if(wpjam_get($_POST, 'action') == $action){
    790             $args       = wpjam_is_assoc_array($args) ? $args : ['callback'=>$args];
    791             $callback   = $args['callback'];
    792             $fields     = $args['fields'] ?? [];
    793 
    794             wpjam_set_die_handler('ajax');
    795 
    796             add_action('wp_ajax_'.$action, fn()=> wpjam_send_json(wpjam_catch($callback, wpjam_if_error(wpjam_fields($fields)->catch('get_parameter', 'POST'), 'send'))));
    797         }
     774        wpjam_register_ajax($action, ['admin'=>true]+(wpjam_is_assoc_array($args) ? $args : ['callback'=>$args]));
    798775    }
    799776
     
    813790            array_walk($args, 'wpjam_add_admin_load');
    814791        }else{
    815             wpjam_admin('add', 'load', $args);
     792            $type   = wpjam_pull($args, 'type') ?: array_find(['base'=>'builtin_page', 'plugin_page'=>'plugin_page'], fn($v, $k)=> isset($args[$k])) ?: '';
     793
     794            if(!in_array($type, ['builtin_page', 'plugin_page'])){
     795                return;
     796            }
     797
     798            wpjam_admin($type.'_load[]', $args);
    816799        }
    817800    }
     
    857840
    858841    function wpjam_register_list_table_action($name, $args){
    859         return WPJAM_List_Table::call_type('action', 'register', $name, $args);
     842        return WPJAM_List_Table_Action::register($name, $args);
    860843    }
    861844
    862845    function wpjam_unregister_list_table_action($name, $args=[]){
    863         return WPJAM_List_Table::call_type('action', 'unregister', $name, $args);
     846        return WPJAM_List_Table_Action::unregister($name, $args);
    864847    }
    865848
    866849    function wpjam_register_list_table_column($name, $field){
    867         return WPJAM_List_Table::call_type('column', 'register', $name, $field);
     850        return WPJAM_List_Table_Column::register($name, $field);
    868851    }
    869852
    870853    function wpjam_unregister_list_table_column($name, $field=[]){
    871         return WPJAM_List_Table::call_type('column', 'unregister', $name, $field);
     854        return WPJAM_List_Table_Column::unregister($name, $field);
    872855    }
    873856
    874857    function wpjam_register_list_table_view($name, $view=[]){
    875         return WPJAM_List_Table::call_type('view', 'register', $name, $view);
     858        return WPJAM_List_Table_View::register($name, $view);
    876859    }
    877860
  • wpjam-basic/trunk/public/wpjam-utils.php

    r3305886 r3310594  
    559559
    560560    if(is_null($key)){
    561         if($index == 0){
    562             array_unshift($arr, $args[0]);
    563         }elseif($index == count($arr)){
    564             array_push($arr, $args[0]);
    565         }else{
    566             array_splice($arr, $index, 0, [$args[0]]);
    567         }
    568     }else{
    569         $value  = is_array($key) ? $key : [$key=>$args[0] ?? ''];
    570 
    571         if($index == 0){
    572             $arr    = $value + $arr;
    573         }else{
    574             $args   = $index == count($arr) ? [$arr, $value] : [array_slice($arr, 0, $index, true), $value, array_slice($arr, $index, null, true)];
    575             $arr    = array_replace(...$args);
    576         }
    577     }
    578 
    579     return $arr;
     561        array_splice($arr, $index, 0, $args);
     562
     563        return $arr;
     564    }
     565
     566    return array_replace(array_slice($arr, 0, $index, true), (is_array($key) ? $key : [$key=>$args[0] ?? '']))+array_slice($arr, $index, null, true);
    580567}
    581568
     
    585572    if($output == 'value'){
    586573        return array_find($arr, $cb);
    587     }elseif(in_array($output, ['key', 'index'])){
    588         $key    = array_find_key($arr, $cb);
    589 
    590         return ($output == 'key' || is_null($key)) ? $key : array_search($key, array_keys($arr), true);
     574    }elseif($output == 'key'){
     575        return array_find_key($arr, $cb);
     576    }elseif($output == 'index'){
     577        return array_search(array_find_key($arr, $cb), array_keys($arr));
    591578    }elseif($output == 'result'){
    592579        foreach($arr as $k => $v){
    593             $result = $cb($v, $k);
    594 
    595             if($result){
     580            if($result  = $cb($v, $k)){
    596581                return $result;
    597582            }
     
    615600
    616601function wpjam_pull(&$arr, $key, ...$args){
    617     if(is_array($key)){
    618         if(wp_is_numeric_array($key)){
    619             $value  = wp_array_slice_assoc($arr, $key);
    620         }else{
    621             $value  = wpjam_map($key, fn($v, $k)=> $arr[$k] ?? $v);
    622             $key    = array_keys($key);
    623         }
    624     }else{
    625         $value  = wpjam_get($arr, $key, array_shift($args));
    626     }
    627 
     602    $value  = is_array($key) ? wp_array_slice_assoc($arr, $key) : wpjam_get($arr, $key, array_shift($args));
    628603    $arr    = wpjam_except($arr, $key);
    629604
     
    633608function wpjam_except($arr, $key){
    634609    if(is_object($arr)){
    635         unset($arr[$key]);
     610        unset($arr->$key);
    636611
    637612        return $arr;
     
    649624    if(wpjam_exists($arr, $key)){
    650625        unset($arr[$key]);
    651     }elseif(str_contains($key, '.')){
    652         $key    = explode('.', $key);
     626    }elseif($key    = wpjam_parse_keys($key)){
    653627        $sub    = &$arr;
    654628
     
    706680
    707681function wpjam_filter($arr, ...$args){
     682    if(!$args || !$args[0]){
     683        return $arr;
     684    }
     685
    708686    if(wpjam_is_assoc_array($args[0])){
    709687        return array_filter($arr, fn($v)=> wpjam_match($v, $args[0], $args[1] ?? 'AND'));
     
    740718    $is_asc = fn($v)=> is_int($v) ? $v === SORT_ASC : strtolower($v) === 'asc';
    741719
    742     if(is_callable($args[0])){
     720    if(wpjam_is_assoc_array($args[0])){
     721        $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], []);
     722    }elseif(is_callable($args[0]) || is_string($args[0])){
    743723        $order  = $args[1] ?? '';
    744         $args   = [array_map($args[0], ($order === 'key' ? array_keys($arr) : $arr)), ($is_asc($order) ? SORT_ASC : SORT_DESC), $args[2] ?? SORT_NUMERIC];
    745     }elseif(!wp_is_numeric_array($args[0])){
    746         $fields = wpjam_is_assoc_array($args[0]) ? $args[0] : [$args[0] => $args[1] ?? SORT_DESC];
    747         $args   = [];
    748 
    749         foreach($fields as $k => $v){
    750             $column = array_column($arr, $k);
    751 
    752             array_push($args, $column, $is_asc($v) ? SORT_ASC : SORT_DESC, is_numeric(current($column)) ? SORT_NUMERIC : SORT_REGULAR);
    753         }
     724
     725        if(is_callable($args[0])){
     726            $column = array_map($args[0], ($order === 'key' ? array_keys($arr) : $arr));
     727            $flag   = $args[2] ?? SORT_NUMERIC;
     728        }else{
     729            $k  = $args[0];
     730            $d  = $args[2] ?? 0;
     731
     732            $column = array_map(fn($v)=> wpjam_get($v, $k, $d), $arr);
     733            $flag   = is_numeric($d) ? SORT_NUMERIC : SORT_REGULAR;
     734        }
     735
     736        $args   = [$column, ($is_asc($order) ? SORT_ASC : SORT_DESC), $flag];
    754737    }
    755738
     
    772755}
    773756
     757function wpjam_parse_keys($key, $type=''){
     758    if($type == '[]'){
     759        $keys   = [];
     760
     761        if(str_contains($key, '[') && !str_starts_with($key, '[') && str_ends_with($key, ']')){
     762            $parts  = preg_split('/(['.preg_quote('[]', '/').'])/', $key, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
     763
     764            if(count($parts) % 3 != 1) {
     765                return [];
     766            }
     767
     768            $keys[] = array_shift($parts);
     769
     770            for($i = 0; $i < count($parts); $i += 3){
     771                if(in_array($parts[$i+1], ['[', ']'], true) || $parts[$i] !== '[' || $parts[$i+2] !== ']'){
     772                    return [];
     773                }
     774
     775                $keys[] = $parts[$i+1];
     776            }
     777        }
     778
     779        return $keys;
     780    }elseif($type == '.'){
     781        return str_contains($key, '.') ? explode('.', $key) : [];
     782    }else{
     783        foreach(['[]', '.'] as $type){
     784            if($keys = wpjam_parse_keys($key, $type)){
     785                return $keys;
     786            }
     787        }
     788
     789        return [];
     790    }
     791}
     792
    774793function wpjam_get($arr, $key, $default=null){
    775794    if(is_object($arr)){
     
    791810        }
    792811
    793         if(!str_contains($key, '.')){
     812        if(str_ends_with($key, '[]')){
     813            $value  = wpjam_get($arr, substr($key, 0, -2), $default);
     814
     815            return is_object($value) ? [$value] : (array)$value;
     816        }
     817
     818        $key    = wpjam_parse_keys($key);
     819
     820        if(!$key){
    794821            return $default;
    795822        }
    796 
    797         $key    = explode('.', $key);
    798823    }
    799824
     
    823848
    824849    if(is_null($key)){
    825         $arr[]  = $key;
     850        $arr[]  = $value;
    826851
    827852        return $arr;
     
    829854
    830855    if(!is_array($key)){
    831         if(wpjam_exists($arr, $key) || !str_contains($key, '.')){
     856        if(wpjam_exists($arr, $key)){
    832857            $arr[$key] = $value;
    833858
     
    835860        }
    836861
    837         $key    = explode('.', $key);
     862        if(str_ends_with($key, '[]')){
     863            $current    = wpjam_get($arr, $key);
     864            $current[]  = $value;
     865
     866            return wpjam_set($arr, substr($key, 0, -2), $current);
     867        }
     868
     869        $key    = wpjam_parse_keys($key) ?: $key;
     870
     871        if(!is_array($key)){
     872            $arr[$key] = $value;
     873
     874            return $arr;
     875        }
    838876    }
    839877
     
    892930            }
    893931        }
    894     }
    895 }
    896 
    897 if(!function_exists('filter_deep')){
    898     function filter_deep($arr, $data){
    899         return wpjam_filter($arr, $callback, true);
    900932    }
    901933}
     
    12461278}
    12471279
    1248 function wpjam_pagenavi($total=0, $echo=true){
    1249     $result = '<div class="pagenavi">'.paginate_links(array_filter([
    1250         'prev_text' => '&laquo;',
    1251         'next_text' => '&raquo;',
    1252         'total'     => $total
    1253     ])).'</div>';
    1254 
    1255     return $echo ? wpjam_echo($result) : $result;
    1256 }
    1257 
    1258 function wpjam_localize_script($handle, $name, $l10n ){
    1259     wp_localize_script($handle, $name, ['l10n_print_after' => $name.' = '.wpjam_json_encode($l10n)]);
    1260 }
    1261 
    12621280function wpjam_is_mobile_number($number){
    12631281    return preg_match('/^0{0,1}(1[3,5,8][0-9]|14[5,7]|166|17[0,1,3,6,7,8]|19[8,9])[0-9]{8}$/', $number);
  • wpjam-basic/trunk/static/form.js

    r3305886 r3310594  
    345345            let show    = args[0] === null ? false : wpjam.compare(args[0], show_if);
    346346
    347             this.add(this.next('br')).toggleClass('hidden', !show);
     347            this.add(this.nextAll('br')).add(this.next('p.after')).add(this.nextAll('p.description')).add(this.prev('p.before')).toggleClass('hidden', !show);
    348348
    349349            (this.is('option, :input') ? this : this.find(':input:not(.disabled)')).prop('disabled', !show);
  • wpjam-basic/trunk/static/script.js

    r3305886 r3310594  
    959959                        let params  = wpjam.parse_params(new URL($a.prop('href')).search);
    960960
    961                         if(wpjam.builtin_page && params.page){
     961                        if(wpjam.builtin_page && (params.page || params.action)){
    962962                            return;
    963963                        }
  • wpjam-basic/trunk/static/style.css

    r3306852 r3310594  
    5656.field-group .sub-field:not(:first-child) > label{min-width:initial;}
    5757
    58 fieldset > .field-group, fieldset > .inline{display:inline-flex; margin:0 0 .5em !important;}
     58fieldset > .field-group,
     59fieldset > .inline{display:inline-flex; margin:0 0 .5em !important;}
    5960fieldset > .field-group:has(> label) > *{margin:.35em 0 .5em!important;}
    6061fieldset > .field-group > label,
     
    157158.add-media span{font-size:18px; margin-right:4px; line-height:30px;}
    158159
    159 div.wpjam-file, div.wpjam-image{display:flex; gap:4px;}
     160div.wpjam-file,
     161div.wpjam-image{display:flex; gap:4px;}
    160162div.wpjam-img{position:relative; cursor:pointer; text-decoration:none; display:inline-block;}
    161163div.wpjam-img img{max-width:300px !important; max-height:300px !important; object-fit:cover;}
     
    204206form table.form-table th a,
    205207form table.form-table td a{text-decoration:none;}
    206 
     208form table.form-table td .before,
     209form table.form-table td .after{margin:0px;}
     210form table.form-table td p.before{margin-bottom:4px;}
     211form table.form-table td p.after{margin-top:4px;}
     212form table.form-table td span.before{margin-right:4px;}
     213form table.form-table td span.after{margin-left:4px;}
    207214form table.form-table td .description{font-size:13px;}
     215form table.form-table td fieldset .after,
     216form table.form-table td fieldset .description{margin-bottom:0.5em;}
     217
    208218form table.form-table td label:has(input:not([type=hidden]):not(.regular-text):not([type=checkbox])) + .description,
    209219form table.form-table td input:not([type=hidden]):not(.regular-text) + .description{display:inline-block; margin-left:6px;}
     220
     221#TB_ajaxContent form table.form-table td .after,
    210222#TB_ajaxContent form table.form-table td .description{padding:0;}
    211223
     
    242254div.summary{font-size:13px; line-height:1.5; margin:1em 0;}
    243255
    244 div.card.response, .widefat td{overflow-wrap:break-word; word-wrap:break-word; word-break:break-word; hyphens:auto;}
    245 
    246 table.wp-list-table th, table.wp-list-table.nowrap td{white-space:nowrap;}
     256div.card.response,
     257.widefat td{overflow-wrap:break-word; word-wrap:break-word; word-break:break-word; hyphens:auto;}
     258
     259table.wp-list-table th,
     260table.wp-list-table.nowrap td{white-space:nowrap;}
    247261
    248262table.wp-list-table.nowrap td{overflow:hidden; text-overflow:ellipsis;}
  • wpjam-basic/trunk/wpjam-basic.php

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