| 1 |
<?php |
| 2 |
/* |
| 3 |
Name: 文章设置 |
| 4 |
URI: https://mp.weixin.qq.com/s/XS3xk-wODdjX3ZKndzzfEg |
| 5 |
Description: 文章设置把文章编辑的一些常用操作,提到文章列表页面,方便设置和操作 |
| 6 |
Version: 2.0 |
| 7 |
*/ |
| 8 |
class WPJAM_Basic_Posts{ |
| 9 |
public static function __callStatic($method, $args){ |
| 10 |
return wpjam_call_option(static::class, $method, ...$args); |
| 11 |
} |
| 12 |
|
| 13 |
public static function get_fields(){ |
| 14 |
return [ |
| 15 |
'excerpt' => ['title'=>'文章摘要', 'sep'=>' ', 'fields'=>['excerpt_optimization' => ['before'=>'未设时:', 'options'=>[ |
| 16 |
0 => 'WordPress 默认方式截取', |
| 17 |
1 => ['label'=>'按� |
| 18 |
�中文最优方式截取', 'fields'=>['excerpt_length'=>['before'=>'长度:', 'type'=>'number', 'class'=>'small-text', 'value'=>200, 'after'=>'中文算2个字节,英文算1个字节']]], |
| 19 |
2 => '直接不显示摘要' |
| 20 |
]]]], |
| 21 |
'list' => ['title'=>'文章列表', 'fields'=>[ |
| 22 |
'support' => ['before'=>'支持:', 'sep'=>' ', 'type'=>'fields', 'fields'=>[ |
| 23 |
'post_list_ajax' => ['label'=>'� |
| 24 |
�面 AJAX 操作', 'value'=>1], |
| 25 |
'upload_external_images' => ['label'=>'上传外部图片操作'], |
| 26 |
]], |
| 27 |
'display' => ['before'=>'显示:', 'sep'=>' ', 'type'=>'fields', 'fields'=>[ |
| 28 |
'post_list_set_thumbnail' => ['label'=>'文章缩略图', 'value'=>1], |
| 29 |
'post_list_author_filter' => ['label'=>'作� |
| 30 |
下拉选择框', 'value'=>1], |
| 31 |
'post_list_sort_selector' => ['label'=>'排序下拉选择框', 'value'=>1] |
| 32 |
]] |
| 33 |
]], |
| 34 |
'other' => ['title'=>'功能优化', 'fields'=>[ |
| 35 |
'remove' => ['before'=>'移除:', 'sep'=>' ', 'type'=>'fields', 'fields'=>[ |
| 36 |
'remove_post_tag' => ['label'=>'移除文章标签功能'], |
| 37 |
'remove_page_thumbnail' => ['label'=>'移除页面特色图片'], |
| 38 |
]], |
| 39 |
'add' => ['before'=>'增强:', 'sep'=>' ', 'type'=>'fields', 'fields'=>[ |
| 40 |
'add_page_excerpt' => ['label'=>'增加页面摘要功能'], |
| 41 |
'404_optimization' => ['label'=>'增强404页面跳转'], |
| 42 |
]] |
| 43 |
]], |
| 44 |
]; |
| 45 |
} |
| 46 |
|
| 47 |
public static function get_the_thumbnail($id, $base){ |
| 48 |
if($base == 'edit'){ |
| 49 |
$thumb = get_the_post_thumbnail($id, [50,50]) ?: ''; |
| 50 |
}else{ |
| 51 |
$thumb = wpjam_get_term_thumbnail_url($id, [100, 100]); |
| 52 |
$thumb = $thumb ? wpjam_tag('img', ['class'=>'wp-term-image', 'src'=>$thumb, 'width'=>50, 'height'=>50]) : ''; |
| 53 |
} |
| 54 |
|
| 55 |
return $thumb ?: '<span class="no-thumbnail">暂无图片</span>'; |
| 56 |
} |
| 57 |
|
| 58 |
public static function get_widget(){ |
| 59 |
return [ |
| 60 |
'classname' => 'widget_posts', |
| 61 |
'widget' => fn($instance)=> ('wpjam_get_'.(wpjam_pull($instance, 'type') ?: 'new').'_posts')(wpjam_except($instance, 'title')), |
| 62 |
'fields' => function(){ |
| 63 |
$types = ['post'=>__('Post')]+array_reduce(get_post_types(['_builtin'=>false]), fn($c, $k)=> is_post_type_viewable($k) && get_object_taxonomies($k) ? $c+[$k=>wpjam_get_post_type_setting($k, 'title')] : $c, []); |
| 64 |
|
| 65 |
$fields = [ |
| 66 |
'title' => ['type'=>'text', 'before'=>'列表标题:', 'class'=>'medium-text'], |
| 67 |
'type' => ['type'=>'select', 'before'=>'列表类型:', 'options'=>['new'=>'最新', 'top_viewd'=>'最高浏览']], |
| 68 |
'number' => ['type'=>'number', 'before'=>'文章数量:', 'class'=>'tiny-text', 'step'=>1, 'min'=>1], |
| 69 |
'class' => ['type'=>'text', 'before'=>'列表样式:', 'class'=>'', 'after'=>'请输� |
| 70 |
� ul 的 class'], |
| 71 |
'post_type' => ['type'=>'checkbox', 'before'=>'文章类型:', 'options'=>$types], |
| 72 |
'thumb' => ['type'=>'checkbox', 'class'=>'checkbox', 'label'=>'显示缩略图'], |
| 73 |
]; |
| 74 |
|
| 75 |
return count($types) <= 1 ? wpjam_except($fields, 'post_type') : $fields; |
| 76 |
} |
| 77 |
]; |
| 78 |
} |
| 79 |
|
| 80 |
// 解决文章类型改变之后跳转错误的问题,原始函数:'wp_old_slug_redirect' 和 'redirect_canonical' |
| 81 |
public static function find_by_name($post_name, $post_type='', $post_status='publish'){ |
| 82 |
$args = array_filter(['post_status'=> $post_status]); |
| 83 |
$with_type = $post_type ? $args+['post_type'=>$post_type] : []; |
| 84 |
$meta = wpjam_get_by_meta('post', '_wp_old_slug', $post_name); |
| 85 |
$posts = $meta ? WPJAM_Post::get_by_ids(array_column($meta, 'post_id')) : []; |
| 86 |
$for_meta = $args+['post_type'=>array_values(array_diff(get_post_types(['public'=>true, 'exclude_from_search'=>false]), ['attachment']))]; |
| 87 |
$post = $posts ? wpjam_find([$with_type, $for_meta], fn($v)=>$v, fn($v)=> $v ? wpjam_find($posts, $v) : '') : null; |
| 88 |
|
| 89 |
if(!$post){ |
| 90 |
$wpdb = $GLOBALS['wpdb']; |
| 91 |
$types = array_map('esc_sql', array_diff(get_post_types(['public'=>true, 'hierarchical'=>false, 'exclude_from_search'=>false]), ['attachment'])); |
| 92 |
$where = "post_type in ('".implode( "', '", $types)."') AND ".$wpdb->prepare("post_name LIKE %s", $wpdb->esc_like($post_name).'%'); |
| 93 |
$ids = $wpdb->get_col("SELECT ID FROM $wpdb->posts WHERE $where"); |
| 94 |
$posts = $ids ? WPJAM_Post::get_by_ids($ids) : []; |
| 95 |
$post = $posts ? wpjam_find([$with_type, $args], fn($v)=>$v, fn($v)=> $v ? wpjam_find($posts, $v) : '') ?: array_first($posts) : null; |
| 96 |
} |
| 97 |
|
| 98 |
return $post ? $post->ID : null; |
| 99 |
} |
| 100 |
|
| 101 |
public static function upload_external_images($id){ |
| 102 |
$bulk = (int)($_POST['bulk'] ?? 0) == 2; |
| 103 |
$content = get_post($id)->post_content; |
| 104 |
|
| 105 |
if($content && !is_serialized($content) && preg_match_all('/<img.*?src=[\'"](.*?)[\'"].*?>/i', $content, $matches)){ |
| 106 |
$urls = array_unique($matches[1]); |
| 107 |
$replace = wpjam_fetch_external_images($urls, $id); |
| 108 |
|
| 109 |
return $replace ? WPJAM_Post::update($id, ['post_content'=>str_replace($urls, $replace, $content)]) : ($bulk ? true : wp_die('文章中无外部图片')); |
| 110 |
} |
| 111 |
|
| 112 |
return $bulk ? true : wp_die('文章中无图片'); |
| 113 |
} |
| 114 |
|
| 115 |
public static function load($screen){ |
| 116 |
$base = $screen->base; |
| 117 |
$object = wpjam_admin((in_array($base, ['post', 'edit', 'upload']) ? 'type' : 'tax').'_object'); |
| 118 |
|
| 119 |
if($base == 'post'){ |
| 120 |
self::get_setting('disable_trackbacks') && wpjam_style('label[for="ping_status"]{display:none !important;}'); |
| 121 |
self::get_setting('disable_autoembed') && $screen->is_block_editor && wpjam_script("wp.domReady(()=> wp.blocks.unregisterBlockType('core/embed'));\n"); |
| 122 |
}elseif(in_array($base, ['edit', 'upload'])){ |
| 123 |
$ptype = $screen->post_type; |
| 124 |
$is_wc_shop = defined('WC_PLUGIN_FILE') && str_starts_with($ptype, 'shop_'); |
| 125 |
|
| 126 |
self::get_setting('post_list_author_filter', 1) && $object->supports('author') && add_action('restrict_manage_posts', function($ptype){ wp_dropdown_users([ |
| 127 |
'name' => 'author', |
| 128 |
'capability' => 'edit_posts', |
| 129 |
'orderby' => 'post_count', |
| 130 |
'order' => 'DESC', |
| 131 |
'show_option_all' => $ptype == 'attachment' ? '所有上传� |
| 132 |
' : '所有作� |
| 133 |
', |
| 134 |
'selected' => (int)wpjam_param('author', 'data'), |
| 135 |
'hide_if_only_one_author' => true, |
| 136 |
]); |
| 137 |
}, 1); |
| 138 |
|
| 139 |
self::get_setting('post_list_sort_selector', 1) && !$is_wc_shop && add_action('restrict_manage_posts', function($ptype){ |
| 140 |
[$columns, , $sortable] = $GLOBALS['wp_list_table']->get_column_info(); |
| 141 |
|
| 142 |
$orderby = wpjam_reduce($sortable, fn($c, $v, $k)=> isset($columns[$k]) ? wpjam_set($c, $k, wp_strip_all_tags($columns[$k])) : $c, []); |
| 143 |
|
| 144 |
echo wpjam_fields([ |
| 145 |
'orderby' => ['options'=>[''=>'排序','ID'=>'ID']+$orderby+($ptype != 'attachment' ? ['modified'=>'修改时间'] : [])], |
| 146 |
'order' => ['options'=>['desc'=>'降序','asc'=>'升序']] |
| 147 |
], [ |
| 148 |
'fields_type' => '', |
| 149 |
'value_callback' => fn($k)=> sanitize_key(wpjam_param($k, 'data')) |
| 150 |
])."\n"; |
| 151 |
}, 99); |
| 152 |
|
| 153 |
if($ptype != 'attachment'){ |
| 154 |
($action = 'upload_external_images') && self::get_setting($action) && wpjam_register_list_table_action($action, [ |
| 155 |
'title' => '上传外部图片', |
| 156 |
'page_title' => '上传外部图片', |
| 157 |
'direct' => true, |
| 158 |
'confirm' => true, |
| 159 |
'bulk' => 2, |
| 160 |
'order' => 9, |
| 161 |
'callback' => [self::class, $action] |
| 162 |
]); |
| 163 |
|
| 164 |
wpjam_style('#bulk-titles, ul.cat-checklist{height:auto; max-height: 14em;}'); |
| 165 |
|
| 166 |
if($ptype == 'page'){ |
| 167 |
wpjam_style('.fixed .column-template{width:15%;}'); |
| 168 |
|
| 169 |
wpjam_register_posts_column('template', '模板', 'get_page_template_slug'); |
| 170 |
} |
| 171 |
} |
| 172 |
|
| 173 |
$width_columns = wpjam_map($object->get_taxonomies(['show_admin_column'=>true]), fn($v)=> '.fixed .column-'.$v->column_name); |
| 174 |
$width_columns = array_merge($width_columns, $object->supports('author') ? ['.fixed .column-author'] : []); |
| 175 |
|
| 176 |
$width_columns && wpjam_style(implode(',', $width_columns).'{width:'.(['14', '12', '10', '8', '7'][count($width_columns)-1] ?? '6').'%}'); |
| 177 |
|
| 178 |
wpjam_style('.fixed .column-date{width:100px;}'); |
| 179 |
}elseif(in_array($base, ['edit-tags', 'term'])){ |
| 180 |
$base == 'edit-tags' && wpjam_style(['.fixed th.column-slug{width:16%;}', '.fixed th.column-description{width:22%;}']); |
| 181 |
|
| 182 |
array_map(fn($v)=> $object->supports($v) ? '' : wpjam_style('.form-field.term-'.$v.'-wrap{display: none;}'), ['slug', 'description', 'parent']); |
| 183 |
} |
| 184 |
|
| 185 |
if($base == 'edit-tags' || ($base == 'edit' && !$is_wc_shop)){ |
| 186 |
wpjam_script(self::get_setting('post_list_ajax', 1) ? <<<'JS' |
| 187 |
setTimeout(()=> { |
| 188 |
wpjam.delegate('#the-list', '.editinline'); |
| 189 |
wpjam.delegate('#doaction'); |
| 190 |
}, 300); |
| 191 |
JS : "wpjam.list_table.ajax = false;\n"); |
| 192 |
|
| 193 |
$base == 'edit' && wpjam_script(<<<'JS' |
| 194 |
inlineEditPost.setBulk = wpjam.enhance(inlineEditPost.setBulk, ()=> $('#the-list').trigger('bulk_edit')); |
| 195 |
inlineEditPost.edit = wpjam.enhance(inlineEditPost.edit, function(id){ |
| 196 |
return ($('#the-list').trigger('quick_edit', typeof(id) === 'object' ? this.getId(id) : id), false); |
| 197 |
}); |
| 198 |
JS); |
| 199 |
|
| 200 |
if(self::get_setting('post_list_ajax', 1)){ |
| 201 |
$pairs[] = ['/(<strong><a class="row-title"[^>]*>.*?<\/a>.*?)(<\/strong>)/is', '$1 [row_action name="set" class="row-action" dashicon="edit"]$2']; |
| 202 |
|
| 203 |
if($base == 'edit'){ |
| 204 |
$pairs[] = ['/(<td class=\'[^\']*('.array_reduce($object->get_taxonomies(['show_in_quick_edit'=>true]), fn($c, $t)=> $c.'|'.preg_quote($t->column_name), 'column-author').')[^\']*\'.*?>.*?)(<\/td>)/is', '$1 <a title="快速编辑" href="javascript:;" class="editinline row-action dashicons dashicons-edit"></a>$3']; |
| 205 |
} |
| 206 |
} |
| 207 |
|
| 208 |
if(self::get_setting('post_list_set_thumbnail', 1) |
| 209 |
&& $object->supports($base == 'edit' ? 'thumbnail,images' : 'thumbnail') |
| 210 |
&& ($base != 'edit'|| $ptype != 'product' || !defined('WC_PLUGIN_FILE')) |
| 211 |
){ |
| 212 |
$pairs[] = ['<a class="row-title" ', fn($id)=> '[row_action name="set" class="wpjam-thumbnail-wrap" fallback="1"]'.self::get_the_thumbnail($id, $base).'[/row_action]']; |
| 213 |
} |
| 214 |
|
| 215 |
isset($pairs) && add_filter('wpjam_single_row', fn($row, $id)=> array_reduce($pairs, fn($c, $p)=> is_callable($p[1]) ? str_replace($p[0], $p[1]($id).$p[0], $c) : wpjam_preg_replace($p[0], $p[1], $c), $row), 10, 2); |
| 216 |
} |
| 217 |
} |
| 218 |
|
| 219 |
public static function init(){ |
| 220 |
self::get_setting('remove_post_tag') && unregister_taxonomy_for_object_type('post_tag', 'post'); |
| 221 |
self::get_setting('remove_page_thumbnail') && remove_post_type_support('page', 'thumbnail'); |
| 222 |
self::get_setting('add_page_excerpt') && add_post_type_support('page', 'excerpt'); |
| 223 |
|
| 224 |
self::get_setting('404_optimization') && wpjam_hook('old_slug_redirect_post_id', fn($id)=> $id ?: self::find_by_name(get_query_var('name'), get_query_var('post_type'))); |
| 225 |
|
| 226 |
if(self::get_setting('excerpt_optimization')){ |
| 227 |
remove_filter('get_the_excerpt', 'wp_trim_excerpt'); |
| 228 |
|
| 229 |
if(self::get_setting('excerpt_optimization') != 2){ |
| 230 |
remove_filter('the_excerpt', 'wp_filter_content_tags'); |
| 231 |
remove_filter('the_excerpt', 'shortcode_unautop'); |
| 232 |
|
| 233 |
wpjam_hook('get_the_excerpt', fn($text='', $post=null)=> $text ?: wpjam_get_post_excerpt($post, (self::get_setting('excerpt_length') ?: 200)), 9, 2); |
| 234 |
} |
| 235 |
} |
| 236 |
} |
| 237 |
} |
| 238 |
|
| 239 |
wpjam_register_option('wpjam-basic', [ |
| 240 |
'title' => '文章设置', |
| 241 |
'plugin_page' => 'wpjam-posts', |
| 242 |
'current_tab' => 'posts', |
| 243 |
'site_default' => true, |
| 244 |
'model' => 'WPJAM_Basic_Posts', |
| 245 |
'admin_load' => ['base'=>['edit', 'upload', 'post', 'edit-tags', 'term']], |
| 246 |
'menu_page' => ['parent'=>'wpjam-basic', 'position'=>4, 'function'=>'tab', 'tabs'=>[ |
| 247 |
'posts' => ['title'=>'文章设置', 'order'=>20, 'summary'=>__FILE__, 'function'=>'option', 'option_name'=>'wpjam-basic'] |
| 248 |
]], |
| 249 |
]); |
| 250 |
|