我有两个使用WP Logging 班它创建了一个名为Logs的自定义post类型,该类型(至少在我的情况下)仅在admin中可见,例如在/wp admin/edit中。php?s&;post\\u状态=全部(&U);post\\U类型=wp\\U日志。
为了更容易判断哪个插件正在创建日志,我添加了几个挂钩。两个插件使用它们的方式相同。他们所做的是:
将可排序类型列添加到管理帖子屏幕,并将类型字段(WP日志库添加)添加到该屏幕在屏幕顶部(日期过滤器旁边)添加一个下拉列表,并允许根据帖子使用的类型值过滤帖子以下是我使用的代码:
// add a sortable Type column to the posts admin
add_filter( \'manage_edit-wp_log_columns\', array( $this, \'type_column\' ), 10, 1 );
add_filter( \'manage_edit-wp_log_sortable_columns\', array( $this, \'sortable_columns\' ), 10, 1 );
add_action( \'manage_wp_log_posts_custom_column\', array( $this, \'type_column_content\' ), 10, 2 );
// filter the log posts admin by log type
add_filter( \'parse_query\', array( $this, \'posts_filter\' ), 10, 1 );
add_action( \'restrict_manage_posts\', array( $this, \'restrict_log_posts\' ) );
/**
* Add a Type column to the posts admin for this post type
*
* @param array $columns
* @return array $columns
*/
public function type_column( $columns ) {
$columns[\'type\'] = __( \'Type\', \'form-processor-mailchimp\' );
return $columns;
}
/**
* Make the Type column in the posts admin for this post type sortable
*
* @param array $columns
* @return array $columns
*/
public function sortable_columns( $columns ) {
$columns[\'type\'] = \'type\';
return $columns;
}
/**
* Add the content for the Type column in the posts admin for this post type
*
* @param string $column_name
* @param int $post_id
*/
public function type_column_content( $column_name, $post_id ) {
if ( \'type\' != $column_name ) {
return;
}
// get wp_log_type
$terms = wp_get_post_terms(
$post_id,
\'wp_log_type\',
array(
\'fields\' => \'names\',
)
);
if ( is_array( $terms ) ) {
echo esc_attr( $terms[0] );
}
}
/**
* Filter log posts by the taxonomy from the dropdown when a value is present
*
* @param object $query
* @return object $query
*/
public function posts_filter( $query ) {
global $pagenow;
$type = \'wp_log\';
$taxonomy = \'wp_log_type\';
if ( is_admin() && \'edit.php\' === $pagenow ) {
if ( isset( $_GET[\'post_type\'] ) && esc_attr( $_GET[\'post_type\'] ) === $type ) {
if ( isset( $_GET[ $taxonomy ] ) && \'\' !== $_GET[ $taxonomy ] ) {
$query->post_type = $type;
$query->tax_query = array(
array(
\'taxonomy\' => $taxonomy,
\'field\' => \'slug\',
\'terms\' => esc_attr( $_GET[ $taxonomy ] ),
),
);
}
}
}
}
/**
* Add a filter form for the log admin so we can filter by wp_log_type taxonomy values
*
* @param object $query
* @return object $query
*/
public function restrict_log_posts() {
$type = \'wp_log\';
$taxonomy = \'wp_log_type\';
// only add filter to post type you want
if ( isset( $_GET[\'post_type\'] ) && esc_attr( $_GET[\'post_type\'] ) === $type ) {
// get wp_log_type
$terms = get_terms(
[
\'taxonomy\' => $taxonomy,
\'hide_empty\' => true,
]
);
?>
<select name="wp_log_type">
<option value=""><?php _e( \'All log types \', \'form-processor-mailchimp\' ); ?></option>
<?php
$current_log_type = isset( $_GET[ $taxonomy ] ) ? esc_attr( $_GET[ $taxonomy ] ) : \'\';
foreach ( $terms as $key => $term ) {
printf(
\'<option value="%s"%s>%s</option>\',
$term->slug,
$term->slug == $current_log_type ? \' selected="selected"\' : \'\',
$term->name
);
}
?>
</select>
<?php
}
}
在这种情况下,两个插件之间的代码是相同的。当然,如果在两个插件中都启用了它,问题是它会复制显示。
在制作之前,我有没有办法检查一下是否已经添加了这些内容?
我认为这值得一试(在所有的过滤器上,使用doing_action
在所有操作上):
if ( ! doing_filter( \'manage_edit-wp_log_columns\' ) ) {
add_filter( \'manage_edit-wp_log_columns\', array( $this, \'type_column\' ), 10, 1 );
}
但这并没有改变任何事情。还有什么我可以试穿的吗?
最合适的回答,由SO网友:Tom J Nowell 整理而成
在代码中,添加如下过滤器:
add_action( \'restrict_manage_posts\', array( $this, \'restrict_log_posts\' ) );
它添加了一个如下开头的函数:
public function restrict_log_posts() {
$type = \'wp_log\';
$taxonomy = \'wp_log_type\';
// only add filter to post type you want
if ( isset( $_GET[\'post_type\'] ) && esc_attr( $_GET[\'post_type\'] ) === $type ) {
// get wp_log_type
$terms = get_terms(
首先,此操作传递post类型,以便通过调整
add_action
并使用它传递的第一个参数:
public function restrict_log_posts( $post_type ) {
$type = \'wp_log\';
$taxonomy = \'wp_log_type\';
// only add filter to post type you want
if ( \'wp_log\' === $post_type ) {
// get wp_log_type
$terms = get_terms(
那么我们可以使用
did_action
要仅在第一次运行它,请执行以下操作:
public function restrict_log_posts( $post_type ) {
if ( did_action( \'restrict_manage_posts\' ) ) {
return;
}
....
但这可能没有预期的效果,而且很粗糙。相反,这个动作根本不属于这个类,应该是一个独立的动作。然后,我们只能在尚未定义函数的情况下定义该函数:
if ( !function_exists(\'restrict_logs_by_type\') ) {
add_action( \'restrict_manage_posts\', \'restrict_logs_by_type\', 10, 1 );
/**
* Add a filter form for the log admin so we can filter by wp_log_type taxonomy values
*
*/
function restrict_logs_by_type( $post_type ) {
$type = \'wp_log\';
$taxonomy = \'wp_log_type\';
// only add filter to post type you want
if ( $type !== $post_type ) {
return;
}
// get wp_log_type
$terms = get_terms([
\'taxonomy\' => $taxonomy,
\'hide_empty\' => true,
]);
if ( is_wp_error( $terms ) || empty( $terms ) ) {
// no terms, or the taxonomy doesn\'t exist, skip
return;
}
?>
<select name="wp_log_type">
<option value=""><?php esc_html_e( \'All log types \', \'form-processor-mailchimp\' ); ?></option>
<?php
$current_log_type = isset( $_GET[ $taxonomy ] ) ? esc_attr( $_GET[ $taxonomy ] ) : \'\';
foreach ( $terms as $key => $term ) {
printf(
\'<option value="%s"%s>%s</option>\',
esc_attr( $term->slug ),
selected( $term->slug, $current_log_type, false ),
esc_html( $term->name )
);
}
?>
</select>
<?php
}
}
注意,我做了一些
significant 改进:
我修复了一个主要的安全漏洞,在选项标记中添加了转义selected
WP提供的功能我将if检查替换为!==
, 让它成为一个守卫。现在,整个函数可以不包含1,并且可读性更强。此外,圈复杂度和NPath复杂度都已降低。该函数现在是独立的,不需要它成为对象或类的一部分。我重命名了该函数以描述它的功能。如果未找到术语,或分类法不存在,此版本将跳过显示下拉列表。如果唯一的项目是“全部”,则没有下拉列表的意义。如果没有这一点,如果没有日志类型或条目,日志屏幕就会崩溃。整个代码段都包装在function_exists
调用,如果函数是由第一个插件加载的,那么第二个插件将不会费心定义和添加它
SO网友:Jonathan Stegall
现在我一直在研究它,我想到了一个可能的解决方案。
// add a filter to check for other plugins that might be filtering the log screen
$are_logs_filtered = apply_filters( \'wp_logging_manage_logs_filtered\', false );
add_filter( \'wp_logging_manage_logs_filtered\', \'__return_true\' );
if ( false === $are_logs_filtered ) {
// add a sortable Type column to the posts admin
add_filter( \'manage_edit-wp_log_columns\', array( $this, \'type_column\' ), 10, 1 );
add_filter( \'manage_edit-wp_log_sortable_columns\', array( $this, \'sortable_columns\' ), 10, 1 );
add_action( \'manage_wp_log_posts_custom_column\', array( $this, \'type_column_content\' ), 10, 2 );
// filter the log posts admin by log type
add_filter( \'parse_query\', array( $this, \'posts_filter\' ), 10, 1 );
add_action( \'restrict_manage_posts\', array( $this, \'restrict_log_posts\' ) );
}
添加
wp_logging_manage_logs_filtered
对于这两个插件,如果在这两个插件上都将其值设置为true,则会导致筛选字段、排序列和列中的内容都只发生一次。
我倾向于认为这是最好的做法,但当然我可能会错过一些东西。