HEX
Server: nginx/1.18.0
System: Linux iZj6c1ieg2jrpk1z5tzi19Z 6.3.9-1.el7.elrepo.x86_64 #1 SMP PREEMPT_DYNAMIC Wed Jun 21 22:18:40 EDT 2023 x86_64
User: www (1001)
PHP: 8.2.4
Disabled: passthru,exec,system,putenv,chroot,chgrp,chown,shell_exec,popen,proc_open,pcntl_exec,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,imap_open,apache_setenv
Upload Files
File: /www/wwwroot/www.cytocare.cn/wp-content/plugins/wpjam-basic/components/wpjam-posts.php
<?php
/*
Name: 文章设置
URI: https://mp.weixin.qq.com/s/XS3xk-wODdjX3ZKndzzfEg
Description: 文章设置把文章编辑的一些常用操作,提到文章列表页面,方便设置和操作
Version: 2.0
*/
class WPJAM_Basic_Posts extends WPJAM_Option_Model{
	public static function get_sections(){
		return ['posts'	=>['title'=>'文章设置',	'fields'=>[
			'excerpt'	=> ['title'=>'文章摘要',	'fields'=>['excerpt_optimization'=>['before'=>'未设文章摘要:',	'options'=>[
				0	=> 'WordPress 默认方式截取',
				1	=> [
					'label'		=> '按照中文最优方式截取',
					'fields'	=> ['excerpt_length'=>['before'=>'文章摘要长度:', 'type'=>'number', 'class'=>'small-text', 'value'=>200, 'after'=>'<strong>中文算2个字节,英文算1个字节</strong>']]
				],
				2	=> '直接不显示摘要'
			]]]],
			'list'		=> ['title'=>'文章列表',	'sep'=>'&emsp;',	'fields'=>[
				'post_list_support'			=> '支持:',
				'post_list_ajax'			=> ['value'=>1,	'label'=>'全面 AJAX 操作'],
				'upload_external_images'	=> ['value'=>0,	'label'=>'上传外部图片操作'],
				'post_list_display'			=> '<br />显示:',
				'post_list_set_thumbnail'	=> ['value'=>1,	'label'=>'文章缩略图'],
				'post_list_author_filter'	=> ['value'=>1,	'label'=>'作者下拉选择框'],
				'post_list_sort_selector'	=> ['value'=>1,	'label'=>'排序下拉选择框'],
			]],
			'other'		=> ['title'=>'功能优化',	'sep'=>'&emsp;',	'fields'=>[
				'remove_post_tag'		=> ['value'=>0,	'label'=>'移除文章标签功能'],
				'remove_page_thumbnail'	=> ['value'=>0,	'label'=>'移除页面特色图片'],
				'add_page_excerpt'		=> ['value'=>0,	'label'=>'增加页面摘要功能'],
				'404_optimization'		=> ['value'=>0,	'label'=>'增强404页面跳转'],
			]],
		]]];
	}

	public static function is_wc_shop($post_type){
		return defined('WC_PLUGIN_FILE') && str_starts_with($post_type, 'shop_');
	}

	public static function find_by_name($post_name, $post_type='', $post_status='publish'){
		$args		= $post_status && $post_status != 'any' ? ['post_status'=> $post_status] : [];
		$with_type	= $post_type && $post_type != 'any' ? $args+['post_type'=>$post_type] : $args;
		$for_meta	= $args+['post_type'=>array_values(array_diff(get_post_types(['public'=>true, 'exclude_from_search'=>false]), ['attachment']))];

		$meta	= wpjam_get_by_meta('post', '_wp_old_slug', $post_name);
		$posts	= $meta ? WPJAM_Post::get_by_ids(array_column($meta, 'post_id')) : [];

		if($with_type){
			if($post = wpjam_find($posts, $with_type)){
				return $post;
			}
		}

		if($post = wpjam_find($posts, $for_meta)){
			return $post;
		}

		$wpdb	= $GLOBALS['wpdb'];
		$types	= array_diff(get_post_types(['public'=>true, 'hierarchical'=>false, 'exclude_from_search'=>false]), ['attachment']);
		$where	= "post_type in ('" . implode( "', '", array_map('esc_sql', $types)) . "')";
		$where	.= ' AND '.$wpdb->prepare("post_name LIKE %s", $wpdb->esc_like($post_name).'%');

		$ids	= $wpdb->get_col("SELECT ID FROM $wpdb->posts WHERE $where");
		$posts	= $ids ? WPJAM_Post::get_by_ids($ids) : [];

		if($with_type){
			if($post = wpjam_find($posts, $with_type)){
				return $post;
			}
		}

		return $args ? wpjam_find($posts, $args) : reset($posts);
	}

	public static function upload_external_images($id){
		$bulk		= (int)wpjam_get_post_parameter('bulk') == 2;
		$object		= wpjam_post($id);
		$content	= $object->content;

		if($content && !is_serialized($content) && preg_match_all('/<img.*?src=[\'"](.*?)[\'"].*?>/i', $content, $matches)){
			$img_urls	= array_unique($matches[1]);
			$replace	= wpjam_fetch_external_images($img_urls, $id);

			if($replace){
				return $object->save(['post_content'=>str_replace($img_urls, $replace, $content)]);
			}

			return $bulk ? true : new WP_Error('error', '文章中无外部图片');
		}

		return $bulk ? true : new WP_Error('error', '文章中无图片');
	}

	public static function filter_single_row($row, $id){
		$object	= get_screen_option('object');

		if(get_current_screen()->base == 'edit'){
			$row	= wpjam_replace('/(<strong>.*?<a class=\"row-title\".*?<\/a>.*?)(<\/strong>)/is', '$1 [row_action name="set" class="row-action" dashicon="edit"]$2', $row);

			if(self::get_setting('post_list_ajax', 1)){
				$columns	= array_map(fn($tax)=> 'column-'.preg_quote($tax->column_name, '/'), $object->get_taxonomies(['show_in_quick_edit'=>true]));
				$row		= wpjam_replace('/(<td class=\'[^\']*('.implode('|', array_merge($columns, ['column-author'])).')[^\']*\'.*?>.*?)(<\/td>)/is', '$1 <a title="快速编辑" href="javascript:;" class="editinline row-action dashicons dashicons-edit"></a>$3', $row);
			}

			if(self::get_setting('post_list_set_thumbnail', 1) && array_any(['thumbnail', 'images'], fn($v)=> $object->supports($v))){
				$thumb	= get_the_post_thumbnail($id, [50,50]) ?: '';
			}
		}else{
			if(self::get_setting('post_list_set_thumbnail', 1) && $object->supports('thumbnail')){
				$thumb	= wpjam_get_term_thumbnail_url($id, [100, 100]);
				$thumb	= $thumb ? wpjam_tag('img', ['class'=>'wp-term-image', 'src'=>$thumb, 'width'=>50, 'height'=>50]) : '';
			}
		}

		if(isset($thumb)){
			$thumb	= $thumb ?: '<span class="no-thumbnail">暂无图片</span>';
			$thumb	= '[row_action name="set" class="wpjam-thumbnail-wrap" fallback="1"]'.$thumb.'[/row_action]';
			$row	= str_replace('<a class="row-title" ', $thumb.'<a class="row-title" ', $row);
		}

		return $row;
	}

	public static function filter_content_save_pre($content){
		if(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE){
			return $content;
		}

		if(!preg_match_all('/<img.*?src=\\\\[\'"](.*?)\\\\[\'"].*?>/i', $content, $matches)){
			return $content;
		}

		$img_urls	= array_unique($matches[1]);

		if($replace	= wpjam_fetch_external_images($img_urls)){
			if(is_multisite()){
				setcookie('wp-saving-post', $_POST['post_ID'].'-saved', time()+DAY_IN_SECONDS, ADMIN_COOKIE_PATH, false, is_ssl());
			}

			$content	= str_replace($img_urls, $replace, $content);
		}

		return $content;
	}

	public static function filter_get_the_excerpt($text='', $post=null){
		$optimization	= self::get_setting('excerpt_optimization');

		if(empty($text) && $optimization){
			remove_filter('get_the_excerpt', 'wp_trim_excerpt');

			if($optimization != 2){
				remove_filter('the_excerpt', 'wp_filter_content_tags');
				remove_filter('the_excerpt', 'shortcode_unautop');

				$length	= self::get_setting('excerpt_length') ?: 200;
				$text	= wpjam_get_post_excerpt($post, $length);
			}
		}

		return $text;
	}

	public static function filter_old_slug_redirect_post_id($post_id){
		// 解决文章类型改变之后跳转错误的问题
		// WP 原始解决函数 'wp_old_slug_redirect' 和 'redirect_canonical'
		if(!$post_id && self::get_setting('404_optimization')){
			$post	= self::find_by_name(get_query_var('name'), get_query_var('post_type'));

			return $post ? $post->ID : $post_id;
		}

		return $post_id;
	}

	public static function load($screen){
		$base		= $screen->base;
		$object		= $screen->get_option('object');
		$style		= [];
		$scripts	= '';

		if($base == 'post'){
			if(self::get_setting('disable_trackbacks')){
				$style[]	= 'label[for="ping_status"]{display:none !important;}';
			}

			if(self::get_setting('disable_autoembed') && $screen->is_block_editor){
				$scripts	= wpjam_remove_pre_tab("
				wp.domReady(function(){
					wp.blocks.unregisterBlockType('core/embed');
				});
				", 4);
			}
		}elseif(in_array($base, ['edit', 'upload'])){
			$style	= ['.fixed .column-date{width:8%;}'];
			$ptype	= $screen->post_type;

			if(self::get_setting('post_list_author_filter', 1) && $object->supports('author')){
				add_action('restrict_manage_posts',	fn($ptype)=> wp_dropdown_users([
					'name'						=> 'author',
					'capability'				=> 'edit_posts',
					'orderby'					=> 'post_count',
					'order'						=> 'DESC',
					'hide_if_only_one_author'	=> true,
					'show_option_all'			=> $ptype == 'attachment' ? '所有上传者' : '所有作者',
					'selected'					=> (int)wpjam_get_data_parameter('author')
				]), 1);
			}

			if(self::get_setting('post_list_sort_selector', 1) && !self::is_wc_shop($ptype)){
				add_action('restrict_manage_posts',	function($ptype){
					[$columns, , $sortable]	= $GLOBALS['wp_list_table']->get_column_info();

					$orderby	= wpjam_array($sortable, fn($k, $v)=> isset($columns[$k]) ? [$v[0], wp_strip_all_tags($columns[$k])] : null);

					echo wpjam_fields([
						'orderby'	=> ['options'=>[''=>'排序','ID'=>'ID']+$orderby+($ptype != 'attachment' ? ['modified'=>'修改时间'] : [])],
						'order'		=> ['options'=>['desc'=>'降序','asc'=>'升序']]
					], [
						'fields_type'		=> '',
						'value_callback'	=> fn($k)=> wpjam_get_data_parameter($k, ['sanitize_callback'=>'sanitize_key'])
					])."\n";
				}, 99);
			}

			if($ptype != 'attachment'){
				add_filter('wpjam_single_row',	[self::class, 'filter_single_row'], 10, 2);

				if(self::get_setting('upload_external_images')){
					wpjam_register_list_table_action('upload_external_images', [
						'title'			=> '上传外部图片',
						'page_title'	=> '上传外部图片',
						'direct'		=> true,
						'confirm'		=> true,
						'bulk'			=> 2,
						'order'			=> 9,
						'callback'		=> [self::class, 'upload_external_images']
					]);
				}

				$style[]	= '#bulk-titles, ul.cat-checklist{height:auto; max-height: 14em;}';

				if($ptype == 'page'){
					$style[]	= '.fixed .column-template{width:15%;}';

					wpjam_register_posts_column('template', '模板', 'get_page_template_slug');
				}elseif($ptype == 'product'){
					if(self::get_setting('post_list_set_thumbnail', 1) && defined('WC_PLUGIN_FILE')){
						wpjam_unregister_list_table_column('thumb');
					}
				}
			}

			$width_columns	= wpjam_map($object->get_taxonomies(['show_admin_column'=>true]), fn($v)=> '.fixed .column-'.$v->column_name);
			$width_columns	= array_merge($width_columns, $object->supports('author') ? ['.fixed .column-author'] : []);

			$count = count($width_columns);

			if($count){
				$width		= ['14%', '12%', '10%', '8%', '7%'][$count-1] ?? '6%';
				$style[]	= implode(',', $width_columns).'{width:'.$width.'}';
			}
		}elseif(in_array($base, ['edit-tags', 'term'])){
			if($base == 'edit-tags'){
				add_filter('wpjam_single_row',	[self::class, 'filter_single_row'], 10, 2);

				$style	= [
					'.fixed th.column-slug{width:16%;}',
					'.fixed th.column-description{width:22%;}',
					'.form-field.term-parent-wrap p{display: none;}',
					'.form-field span.description{color:#666;}'
				];
			}

			$style	= array_merge($style, wpjam_map(['slug', 'description', 'parent'], fn($v)=> $object->supports($v) ? '' : '.form-field.term-'.$v.'-wrap{display: none;}'));	
		}

		if($base == 'edit-tags' || ($base == 'edit' && !self::is_wc_shop($ptype))){
			if(self::get_setting('post_list_ajax', 1)){
				wpjam_add_item('page_setting', 'ajax_list_action', true);

				$scripts	.= wpjam_remove_pre_tab("
				$(window).load(function(){
					wpjam.delegate('#the-list', '.editinline');
					wpjam.delegate('#doaction');
				});
				", 3);
			}

			$scripts	.= $base == 'edit' ? wpjam_remove_pre_tab("
			wpjam.add_extra_logic(inlineEditPost, 'setBulk', function(){
				$('#the-list').trigger('bulk_edit');
			});

			wpjam.add_extra_logic(inlineEditPost, 'edit', function(id){
				if(typeof(id) === 'object'){
					id = this.getId(id);
				}

				$('#the-list').trigger('quick_edit', id);

				return false;
			});
			", 2) : '';
		}

		if($scripts){
			wp_add_inline_script('jquery', "jQuery(function($){".$scripts."\n});");
		}

		if($style){
			wp_add_inline_style('list-tables', "\n".implode("\n", $style));
		}
	}

	public static function init(){
		if(self::get_setting('remove_post_tag')){
			unregister_taxonomy_for_object_type('post_tag', 'post');
		}

		if(self::get_setting('remove_page_thumbnail')){
			remove_post_type_support('page', 'thumbnail');
		}

		if(self::get_setting('add_page_excerpt')){
			add_post_type_support('page', 'excerpt');
		}
	}

	public static function add_hooks(){
		add_filter('get_the_excerpt',			[self::class, 'filter_get_the_excerpt'], 9, 2);
		add_filter('old_slug_redirect_post_id',	[self::class, 'filter_old_slug_redirect_post_id']);
	}
}

class WPJAM_Posts_Widget extends WP_Widget{
	public function __construct() {
		parent::__construct('wpjam-posts', 'WPJAM - 文章列表', [
			'classname'						=> 'widget_posts',
			'customize_selective_refresh'	=> true,
			'show_instance_in_rest'			=> false,
		]);

		$this->alt_option_name = 'widget_wpjam_posts';
	}

	public function widget($args, $instance){
		$args['widget_id']	??= $this->id;

		echo $args['before_widget'];

		if(!empty($instance['title'])){
			echo $args['before_title'].wpjam_pull($instance, 'title').$args['after_title'];
		}

		$instance['posts_per_page']	= wpjam_pull($instance, 'number') ?: 5;

		$type	= wpjam_pull($instance, 'type') ?: 'new';

		if($type == 'new'){
			echo wpjam_get_new_posts($instance);
		}elseif($type == 'top_viewd'){
			echo wpjam_get_top_viewd_posts($instance);
		}

		echo $args['after_widget'];
	}

	public function form($instance){
		$types	= ['new'=>'最新', 'top_viewd'=>'最高浏览'];
		$ptypes	= ['post'=>__('Post')];

		foreach(get_post_types(['_builtin'=>false]) as $ptype){
			if(is_post_type_viewable($ptype) && get_object_taxonomies($ptype)){
				$ptypes[$ptype]	= wpjam_get_post_type_setting($ptype, 'title');
			}
		}

		$fields		= [
			'title'		=> ['type'=>'text',		'title'=>'标题:',		'class'=>'widefat'],
			'type'		=> ['type'=>'select',	'title'=>'列表类型:',	'class'=>'widefat',	'options'=>$types],
			'post_type'	=> ['type'=>'checkbox',	'title'=>'文章类型:',	'options'=>$ptypes],
			'number'	=> ['type'=>'number',	'before'=>'文章数量:	',	'class'=>'medium-text',	'step'=>1,	'min'=>1],
			'class'		=> ['type'=>'text',		'before'=>'列表Class:',	'class'=>'medium-text'],
			'thumb'		=> ['type'=>'checkbox',	'class'=>'checkbox',	'label'=>'显示缩略图'],
		];

		if(count($ptypes) <= 1){
			unset($fields['post_type']);
		}

		foreach($fields as $key => &$field){
			$field['id']	= $this->get_field_id($key);
			$field['name']	= $this->get_field_name($key);

			if(isset($instance[$key])){
				$field['value']	= $instance[$key];
			}
		}

		wpjam_fields($fields, ['wrap_tag'=>'p']);
	}
}

wpjam_register_option('wpjam-basic', [
	'title'			=> '文章设置',
	'plugin_page'	=> 'wpjam-posts',
	'current_tab'	=> 'posts',
	'site_default'	=> true,
	'model'			=> 'WPJAM_Basic_Posts',
	'admin_load'	=> ['base'=>['edit', 'upload', 'post', 'edit-tags', 'term']],
	'menu_page'		=> [
		'parent'		=> 'wpjam-basic',
		'menu_slug'		=> 'wpjam-posts',
		'position'		=> 4,
		'function'		=> 'tab',
		'tabs'			=> ['posts'=>[
			'title'			=> '文章设置',
			'function'		=> 'option',
			'option_name'	=> 'wpjam-basic',
			'site_default'	=> true,
			'order'			=> 20,
			'summary'		=> __FILE__,
		]]
	],
]);