晋太元中,武陵人捕鱼为业。缘溪行,忘路之远近。忽逢桃花林,夹岸数百步,中无杂树,芳草鲜美,落英缤纷。渔人甚异之,复前行,欲穷其林。 林尽水源,便得一山,山有小口,仿佛若有光。便舍船,从口入。初极狭,才通人。复行数十步,豁然开朗。土地平旷,屋舍俨然,有良田、美池、桑竹之属。阡陌交通,鸡犬相闻。其中往来种作,男女衣着,悉如外人。黄发垂髫,并怡然自乐。 见渔人,乃大惊,问所从来。具答之。便要还家,设酒杀鸡作食。村中闻有此人,咸来问讯。自云先世避秦时乱,率妻子邑人来此绝境,不复出焉,遂与外人间隔。问今是何世,乃不知有汉,无论魏晋。此人一一为具言所闻,皆叹惋。余人各复延至其家,皆出酒食。停数日,辞去。此中人语云:“不足为外人道也。”(间隔 一作:隔绝) 既出,得其船,便扶向路,处处志之。及郡下,诣太守,说如此。太守即遣人随其往,寻向所志,遂迷,不复得路。 南阳刘子骥,高尚士也,闻之,欣然规往。未果,寻病终。后遂无问津者。
|
Server : Apache System : Linux srv.rainic.com 4.18.0-553.47.1.el8_10.x86_64 #1 SMP Wed Apr 2 05:45:37 EDT 2025 x86_64 User : rainic ( 1014) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/stando/www/wp-content/plugins/uwac/adminframework/classes/posttype/ |
Upload File : |
<?php
namespace PostTypes;
/**
* PostType
*
* Used to help manage a post types columns in the admin table
*
* @link http://github.com/jjgrainger/PostTypes/
* @author jjgrainger
* @link http://jjgrainger.co.uk
* @version 1.1.1
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*/
class PostType
{
/**
* The post type name.
*
* @var string
*/
public $postTypeName;
/**
* The human friendly singular name.
*
* @var string
*/
public $singular;
/**
* The human friendly plural name.
*
* @var string
*/
public $plural;
/**
* The post type slug.
*
* @var string
*/
public $slug;
/**
* The options passed for the post type.
*
* @var array
*/
public $options;
/**
* The labels passed for the post type.
*
* @var array
*/
public $labels;
/**
* An array of taxonomy names attached to the post type.
*
* @var array
*/
public $taxonomies = [];
/**
* An array of new taxonomy objects.
*
* @var array
*/
public $addTaxonomies = [];
/**
* An array of existing taxonomies attached to the class.
*
* @var array
*/
public $existingTaxonomies = [];
/**
* An array of taxonomies to use for filters.
*
* @var array
*/
public $filters = [];
/**
* The columns object for managing post type columns.
*
* @var PostTypes\Columns;
*/
public $columns = false;
/**
* The textdomain to use for translation.
*
* @var string
*/
public $textdomain = 'cpt';
/**
* Register a custom post type.
*
* @param mixed $names The name(s) of the post type, accepts (post type name, slug, plural, singular).
* @param array $options User submitted options.
*/
public function __construct($names, $options = [], $labels = [])
{
// create necessary post type names
$this->names($names);
// set the options
$this->options($options);
// set the labels
$this->labels($labels);
// create a columns object
$this->columns = new Columns();
// add actions and filters
$this->initialize();
}
/**
* Set the post type names.
*
* @param mixed $names a post type name as string or an array of names
*/
public function names($names)
{
// if a string is passed
if (!is_array($names)) {
$names = ['name' => $names];
}
// set the postTypeName
$this->postTypeName = $names['name'];
// an array of required names
$required = [
// 'name',
'singular',
'plural',
'slug',
];
foreach ($required as $key) {
// if the name has not been passed, generate it
if (!isset($names[$key])) {
// if it is the singular/plural make the post type name human friendly
if ($key === 'singular' || $key === 'plural') {
$name = ucwords(strtolower(str_replace(['-', '_'], ' ', $this->postTypeName)));
// if plural add an s
if ($key === 'plural') {
$name .= 's';
}
// if the slug, slugify the post type name
} elseif ($key === 'slug') {
$name = strtolower(str_replace([' ', '_'], '-', $this->postTypeName));
}
// otherwise use the name passed
} else {
$name = $names[$key];
}
// set the name
$this->$key = $name;
}
}
/**
* Set the post type options.
*
* @param array $options an array of post type options
*/
public function options($options)
{
// default options.
$defaults = [
'public' => true,
'rewrite' => [
'slug' => $this->slug,
],
];
// merge user submitted options with defaults.
$this->options = array_replace_recursive($defaults, $options);
}
/**
* Set the post type labels.
*
* @param array $labels an array of post type options
*/
public function labels($labels = [])
{
// default labels.
$defaults = [
'name' => sprintf(__('%s', $this->textdomain), $this->plural),
'singular_name' => sprintf(__('%s', $this->textdomain), $this->singular),
'menu_name' => sprintf(__('%s', $this->textdomain), $this->plural),
'all_items' => sprintf(__('%s', $this->textdomain), $this->plural),
'add_new' => __('Add New', $this->textdomain),
'add_new_item' => sprintf(__('Add New %s', $this->textdomain), $this->singular),
'edit_item' => sprintf(__('Edit %s', $this->textdomain), $this->singular),
'new_item' => sprintf(__('New %s', $this->textdomain), $this->singular),
'view_item' => sprintf(__('View %s', $this->textdomain), $this->singular),
'search_items' => sprintf(__('Search %s', $this->textdomain), $this->plural),
'not_found' => sprintf(__('No %s found', $this->textdomain), $this->plural),
'not_found_in_trash' => sprintf(__('No %s found in Trash', $this->textdomain), $this->plural),
'parent_item_colon' => sprintf(__('Parent %s:', $this->textdomain), $this->singular),
'title' => sprintf(__('Enter %s title here', $this->textdomain), $this->singular),
];
// merge user submitted labels with defaults.
$this->labels = array_replace_recursive($defaults, $labels);
$this->options['labels'] = $this->labels;
}
/**
* Change Default Post Type Title: "Enter title here"
*/
public function changeDefaultTitle($title){
$screen = get_current_screen();
if ($this->postTypeName == $screen->post_type ) {
$title = $this->options['labels']['title'];
}
return $title;
}
/**
* Register a taxonomy to the Post Type.
*
* @see http://codex.wordpress.org/Function_Reference/register_taxonomy
*
* @param mixed $names The names for the taxonomy.
* @param array $options Taxonomy options.
*/
public function taxonomy($names, $options = [])
{
// if only the name is passed, create an array
if (!is_array($names)) {
$names = ['name' => $names];
}
// add taxonomy name to the list
$this->taxonomies[] = $names['name'];
// create taxonomy and options for registering later
$this->addTaxonomies[$names['name']] = new Taxonomy($names, $options);
$this->addTaxonomies[$names['name']]->textdomain($this->textdomain);
}
/**
* Set which filters appear on the admin table page for the post type.
*
* @param array $filters An array of taxonomy filters to display.
*/
public function filters($filters)
{
$this->filters = $filters;
}
/**
* the columns object for the post type.
*
* @return PostType\Columns;
*/
public function columns()
{
return $this->columns;
}
/**
* Use this function to set the menu icon in the admin dashboard. Since WordPress v3.8
* dashicons are used. For more information see @link http://melchoyce.github.io/dashicons/.
*
* @param string $icon dashicon name
*/
public function icon($icon)
{
$this->options['menu_icon'] = $icon;
}
/**
* Flush rewrite rules programatically.
*/
public function flush()
{
flush_rewrite_rules();
}
/**
* set the textdomain for the post type.
*
* @param string $textdomain Textdomain used for translation.
*/
public function translation($textdomain)
{
$this->textdomain = $textdomain;
}
/**
* bind methods to WordPress actions and filters.
*/
public function initialize()
{
// register taxonomies.
add_action('init', array(&$this, 'registerTaxonomies'));
// register the post type.
add_action('init', array(&$this, 'registerPostType'));
// register existing taxonomies.
add_action('init', array(&$this, 'registerExistingTaxonomies'));
// add taxonomy to admin edit columns.
add_filter('manage_edit-'.$this->postTypeName.'_columns', array(&$this, 'modifyColumns'));
// populate the taxonomy columns with the posts terms.
add_action('manage_'.$this->postTypeName.'_posts_custom_column', array(&$this, 'populateColumns'), 10, 2);
// add filter select option to admin edit.
add_action('restrict_manage_posts', array(&$this, 'modifyFilters'));
// run filter to make columns sortable.
add_filter('manage_edit-'.$this->postTypeName.'_sortable_columns', array(&$this, 'setSortableColumns'));
// run action that sorts columns on request.
add_action('load-edit.php', array(&$this, 'loadEdit'));
// rewrite post update messages
add_filter('post_updated_messages', array(&$this, 'modifyUpdatedMessages'));
add_filter('bulk_post_updated_messages', array(&$this, 'modifyBulkUpdateMessages'), 10, 2);
// change default post title: "Enter title here"
add_filter('enter_title_here', [&$this, 'changeDefaultTitle']);
}
/**
* Register the post type.
*/
public function registerPostType()
{
// check that the post type doesn't already exist.
if (!post_type_exists($this->postTypeName)) {
// register the post type.
register_post_type($this->postTypeName, $this->options);
}
}
/**
* Register the post type taxonomies.
*/
public function registerTaxonomies()
{
// foreach taxonomy to register to the post type
foreach ($this->addTaxonomies as $name => $taxonomy) {
// if the taxonomy exists
if (taxonomy_exists($name)) {
// save the taxonomy name to register later
$this->existingTaxonomies[] = $name;
} else {
// create new taxonomy and add to the post
register_taxonomy($name, $this->postTypeName, $taxonomy->options);
}
}
}
/**
* Register existing taxonomies to the post type.
*/
public function registerExistingTaxonomies()
{
// foreach existing taxonomy
foreach ($this->existingTaxonomies as $taxonomy_name) {
// register taxonomy to the post type
register_taxonomy_for_object_type($taxonomy_name, $this->postTypeName);
}
}
/**
* Modify the post type admin filters.
*
* @param string $postType the current post type being viewed
*/
public function modifyFilters($postType)
{
global $wp_query;
$filters = [];
// must set this to the post type you want the filter(s) displayed on.
if ($postType == $this->postTypeName) {
// if we have user supplied filters use them
if (!empty($this->filters)) {
$filters = $this->filters;
// otherwise add taxonomies as fitlers
} elseif (!empty($this->taxonomies)) {
foreach ($this->taxonomies as $taxonomy) {
$filters[] = $taxonomy;
}
}
// foreach of the taxonomies we want to create filters for
foreach ($filters as $taxonomy_name) {
// object for taxonomy, doesn't contain the terms
$tax = get_taxonomy($taxonomy_name);
// get taxonomy terms and order by name
$args = [
'orderby' => 'name',
'hide_empty' => false,
];
// get taxonomy terms
$terms = get_terms($taxonomy_name, $args);
// if we have terms
if ($terms) {
// set up select box
printf(' <select name="%s" class="postform">', $taxonomy_name);
// default show all
printf('<option value="0">%s</option>', sprintf(__('Show all %s', $this->textdomain), $tax->label));
// foreach term create an option field
foreach ($terms as $term) {
// if filtered by this term make it selected
if (isset($_GET[$taxonomy_name]) && $_GET[$taxonomy_name] === $term->slug) {
$format = '<option value="%s" selected="selected">%s (%s)</option>';
printf($format, $term->slug, $term->name, $term->count);
// create option for taxonomy
} else {
printf('<option value="%s">%s (%s)</option>', $term->slug, $term->name, $term->count);
}
}
// end the select field
echo '</select> ';
}
}
}
}
/**
* Modify the post type columns with the columns object.
*
* @param array $columns an array of admin table columns
* @return array an array of admin tbale columns
*/
public function modifyColumns($columns)
{
// if the user has supplied a columns array use that
if (!empty($this->columns()->items)) {
return $this->columns()->items;
}
// otherwise add the taxonomies to the columns
if (!empty($this->taxonomies)) {
// determine what column the taxomies follow
if ($this->postTypeName === 'post' || in_array('post_tag', $this->taxonomies)) {
$after = 'tags';
} elseif (in_array('categories', $this->taxonomies)) {
$after = 'categories';
} elseif (post_type_supports($this->postTypeName, 'author')) {
$after = 'author';
} else {
$after = 'title';
}
// create a new columns array
$newColumns = [];
// cycle through the current columns
foreach ($columns as $key => $label) {
// add columsn to new columns array
$newColumns[$key] = $label;
// if this column is where the taxonomies come after
if ($key === $after) {
// cycle through taxonomies
foreach ($this->taxonomies as $taxonomy) {
// if is a custom taxonomy
if ($taxonomy !== 'category' && $taxonomy !== 'post_tag') {
// get the taxonomy object for labels
$taxonomy_object = get_taxonomy($taxonomy);
$label = $taxonomy_object->labels->name;
// column key is the slug, value is friendly name
$newColumns[$taxonomy] = sprintf(__('%s', $this->textdomain), $label);
}
}
}
}
// set columns to new ones with taxonomies
$columns = $newColumns;
}
// if user has made added custom columns
foreach ($this->columns()->add as $key => $label) {
// if user has assigned a custom position
if (isset($this->columns()->positions[$key])) {
// get the position
$position = $this->columns()->positions[$key];
// split columns array into two
$start = array_slice($columns, 0, $position, true);
$end = array_slice($columns, $position, count($columns) - 1, true);
// insert column between two parts
$columns = $start + [$key => $label] + $end;
} else {
$columns[$key] = $label;
}
}
// any columns the user has hidden
foreach ($this->columns()->hide as $key) {
unset($columns[$key]);
}
// overide with new columns
return $columns;
}
/**
* populate the columns for the admin table.
*
* @param string $column the column name
* @param int $post_id the post id
*/
public function populateColumns($column, $post_id)
{
// get wordpress $post object
global $post;
// use custom populate
if (isset($this->columns()->populate[$column])) {
call_user_func_array($this->columns()->populate[$column], [$column, $post_id]);
return;
}
switch ($column) {
// if column is a taxonomy associated with the post type
case taxonomy_exists($column):
// get the taxonomy for the post
$terms = get_the_terms($post_id, $column);
// if we have terms
if (!empty($terms)) {
$output = [];
// loop through each term, linking to the 'edit posts' page for the specific term
foreach ($terms as $term) {
// output is an array of terms associated with the post
$output[] = sprintf(
'<a href="%s">%s</a>', // Define link format
esc_url(add_query_arg(['post_type' => $post->post_type, $column => $term->slug], 'edit.php')), // Create filter url
esc_html(sanitize_term_field('name', $term->name, $term->term_id, $column, 'display')) // Create friendly term name
);
}
// join the terms, separating them with a comma
echo implode(', ', $output);
// if no terms found.
} else {
// get the taxonomy object for labels
$taxonomy_object = get_taxonomy($column);
// echo no terms.
printf(__('No %s', $this->textdomain), $taxonomy_object->labels->name);
}
break;
// if column is for the post ID
case 'post_id':
echo $post->ID;
break;
// if the column is prepended with 'meta_', retrieve the meta values and display them
case preg_match('/^meta_/', $column) ? true : false:
// meta_book_author (meta key = book_author)
$x = substr($column, 5);
$meta = get_post_meta($post->ID, $x);
echo implode(', ', $meta);
break;
// if the column is post thumbnail
case 'icon':
// create the edit link
$link = esc_url(add_query_arg(['post' => $post->ID, 'action' => 'edit'], 'post.php'));
// if it post has a featured image
if (has_post_thumbnail()) {
// display post featured image with edit link
echo '<a href="'.$link.'">';
the_post_thumbnail(array(60, 60));
echo '</a>';
} else {
// display default media image with link
$image = site_url('/wp-includes/images/crystal/default.png');
echo '<a href="'.$link.'">';
echo '<img src="'.$image.'" alt="'.$post->post_title.'" />';
echo '</a>';
}
break;
}
}
/**
* Set the columns that are sortable.
*
* @param array $columns the sortable columns
* @return array an array of sortable columns
*/
public function setSortableColumns($columns)
{
if (!empty($this->columns()->sortable)) {
// for each sortable column
foreach ($this->columns()->sortable as $column => $values) {
// make an array to merge into wordpress sortable columns
$sortable_columns[$column] = $values[0];
}
// merge sortable columns array into wordpress sortable columns
$columns = array_merge($sortable_columns, $columns);
}
return $columns;
}
/**
* add filter to sort sortable columns.
*/
public function loadEdit()
{
// Run filter to sort columns when requested
add_filter('request', [&$this, 'sortColumns']);
}
/**
* Sort data via the requested column.
*
* @param array $vars the request query vars
* @return array the request query vars
*/
public function sortColumns($vars)
{
// cycle through all sortable columns submitted by the user
foreach ($this->columns()->sortable as $column => $values) {
// retrieve the meta key from the user submitted array of sortable columns
$meta_key = $values[0];
// if the optional parameter is set and is set to true
if (isset($values[1]) && true === $values[1]) {
// vaules needed to be ordered by integer value
$orderby = 'meta_value_num';
} else {
// values are to be order by string value
$orderby = 'meta_value';
}
// check if we're viewing this post type
if (isset($vars['post_type']) && $this->postTypeName == $vars['post_type']) {
// find the meta key we want to order posts by
if (isset($vars['orderby']) && $meta_key === $vars['orderby']) {
$add = [];
if (!taxonomy_exists($meta_key)) {
$add = [
'meta_key' => $meta_key,
'orderby' => $orderby,
];
}
// merge the query vars with our custom variables
$vars = array_merge(
$vars,
$add
);
}
}
}
return $vars;
}
/**
* Internal function that modifies the post type names in updated messages.
*
* @param array $messages an array of post updated messages
*
* @return array modified bulk updated messages
*/
public function modifyUpdatedMessages($messages)
{
$post = get_post();
$singular = $this->singular;
$revision = false;
if (isset($_GET['revision'])) {
$revision_title = wp_post_revision_title((int) $_GET['revision'], false);
$message = __('%2$s restored to revision from %1$s', $this->textdomain);
$revision = sprintf($message, $revision_title, $singular);
}
$messages[$this->postTypeName] = [
0 => '',
1 => sprintf(__('%s updated.', $this->textdomain), $singular),
2 => __('Custom field updated.', $this->textdomain),
3 => __('Custom field deleted.', $this->textdomain),
4 => sprintf(__('%s updated.', $this->textdomain), $singular),
5 => $revision,
6 => sprintf(__('%s updated.', $this->textdomain), $singular),
7 => sprintf(__('%s saved.', $this->textdomain), $singular),
8 => sprintf(__('%s submitted.', $this->textdomain), $singular),
9 => sprintf(
__('%2$s scheduled for: <strong>%1$s</strong>.', $this->textdomain),
date_i18n(__('M j, Y @ G:i', $this->textdomain), strtotime($post->post_date)),
$singular
),
10 => sprintf(__('%s draft updated.', $this->textdomain), $singular),
];
return $messages;
}
/**
* Internal function that modifies the post type names in bulk updated messages.
*
* @param array $messages an array of bulk updated messages
*
* @return array modified bulk updated messages
*/
public function modifyBulkUpdateMessages($bulk_messages, $bulk_counts)
{
$singular = $this->singular;
$plural = $this->plural;
$bulk_messages[$this->postTypeName] = [
'updated' => _n(
'%s '.$singular.' updated.',
'%s '.$plural.' updated.',
$bulk_counts['updated']
),
'locked' => _n(
'%s '.$singular.' not updated, somebody is editing it.',
'%s '.$plural.' not updated, somebody is editing them.',
$bulk_counts['locked']
),
'deleted' => _n(
'%s '.$singular.' permanently deleted.',
'%s '.$plural.' permanently deleted.',
$bulk_counts['deleted']
),
'trashed' => _n(
'%s '.$singular.' moved to the Trash.',
'%s '.$plural.' moved to the Trash.',
$bulk_counts['trashed']
),
'untrashed' => _n(
'%s '.$singular.' restored from the Trash.',
'%s '.$plural.' restored from the Trash.',
$bulk_counts['untrashed']
),
];
return $bulk_messages;
}
}