函数文档

_wp_ajax_add_hierarchical_term()

💡 云策文档标注

概述

_wp_ajax_add_hierarchical_term() 是一个 WordPress AJAX 处理函数,用于通过 AJAX 请求添加分层分类法(如分类目录)的新术语。它验证用户权限、处理术语名称和父级关系,并返回更新后的术语列表和父级下拉菜单数据。

关键要点

  • 函数通过 AJAX 处理添加分层术语的请求,支持分类目录等分类法。
  • 验证 AJAX 引用和用户权限(edit_terms 能力),失败时调用 wp_die()。
  • 从 POST 数据中提取术语名称和父级 ID,使用 wp_insert_term() 插入新术语。
  • 处理父级术语时,会更新术语检查列表和父级下拉菜单,通过 WP_Ajax_Response 返回响应。
  • 使用多个核心函数,如 check_ajax_referer()、sanitize_title()、wp_terms_checklist() 和 wp_dropdown_categories()。
  • 包含一个过滤器 post_edit_category_parent_dropdown_args,用于修改父级下拉菜单参数。

代码示例

// 示例代码展示了函数的核心逻辑片段
$taxonomy = get_taxonomy( substr( $action, 4 ) );
check_ajax_referer( $action, '_ajax_nonce-add-' . $taxonomy->name );

if ( ! current_user_can( $taxonomy->cap->edit_terms ) ) {
    wp_die( -1 );
}

$names = explode( ',', $_POST[ 'new' . $taxonomy->name ] );
$parent = isset( $_POST[ 'new' . $taxonomy->name . '_parent' ] ) ? (int) $_POST[ 'new' . $taxonomy->name . '_parent' ] : 0;

$cat_id = wp_insert_term( $cat_name, $taxonomy->name, array( 'parent' => $parent ) );

$x = new WP_Ajax_Response( $add );
$x->send();

注意事项

  • 函数仅处理分层分类法,如分类目录,非分层分类法可能不适用。
  • AJAX 请求必须包含正确的 action 参数和 nonce 验证,否则会失败。
  • 父级 ID 处理中,负值会被重置为 0,确保层级关系正确。
  • 错误处理通过 is_wp_error() 检查 wp_insert_term() 的返回值,失败时跳过该术语。
  • 输出使用输出缓冲(ob_start() 和 ob_get_clean())捕获 HTML 内容,确保响应数据格式正确。

📄 原文内容

Handles adding a hierarchical term via AJAX.

Source

function _wp_ajax_add_hierarchical_term() {
	$action   = $_POST['action'];
	$taxonomy = get_taxonomy( substr( $action, 4 ) );
	check_ajax_referer( $action, '_ajax_nonce-add-' . $taxonomy->name );

	if ( ! current_user_can( $taxonomy->cap->edit_terms ) ) {
		wp_die( -1 );
	}

	$names  = explode( ',', $_POST[ 'new' . $taxonomy->name ] );
	$parent = isset( $_POST[ 'new' . $taxonomy->name . '_parent' ] ) ? (int) $_POST[ 'new' . $taxonomy->name . '_parent' ] : 0;

	if ( 0 > $parent ) {
		$parent = 0;
	}

	if ( 'category' === $taxonomy->name ) {
		$post_category = isset( $_POST['post_category'] ) ? (array) $_POST['post_category'] : array();
	} else {
		$post_category = ( isset( $_POST['tax_input'] ) && isset( $_POST['tax_input'][ $taxonomy->name ] ) ) ? (array) $_POST['tax_input'][ $taxonomy->name ] : array();
	}

	$checked_categories = array_map( 'absint', (array) $post_category );
	$popular_ids        = wp_popular_terms_checklist( $taxonomy->name, 0, 10, false );

	foreach ( $names as $cat_name ) {
		$cat_name          = trim( $cat_name );
		$category_nicename = sanitize_title( $cat_name );

		if ( '' === $category_nicename ) {
			continue;
		}

		$cat_id = wp_insert_term( $cat_name, $taxonomy->name, array( 'parent' => $parent ) );

		if ( ! $cat_id || is_wp_error( $cat_id ) ) {
			continue;
		} else {
			$cat_id = $cat_id['term_id'];
		}

		$checked_categories[] = $cat_id;

		if ( $parent ) { // Do these all at once in a second.
			continue;
		}

		ob_start();

		wp_terms_checklist(
			0,
			array(
				'taxonomy'             => $taxonomy->name,
				'descendants_and_self' => $cat_id,
				'selected_cats'        => $checked_categories,
				'popular_cats'         => $popular_ids,
			)
		);

		$data = ob_get_clean();

		$add = array(
			'what'     => $taxonomy->name,
			'id'       => $cat_id,
			'data'     => str_replace( array( "n", "t" ), '', $data ),
			'position' => -1,
		);
	}

	if ( $parent ) { // Foncy - replace the parent and all its children.
		$parent  = get_term( $parent, $taxonomy->name );
		$term_id = $parent->term_id;

		while ( $parent->parent ) { // Get the top parent.
			$parent = get_term( $parent->parent, $taxonomy->name );
			if ( is_wp_error( $parent ) ) {
				break;
			}
			$term_id = $parent->term_id;
		}

		ob_start();

		wp_terms_checklist(
			0,
			array(
				'taxonomy'             => $taxonomy->name,
				'descendants_and_self' => $term_id,
				'selected_cats'        => $checked_categories,
				'popular_cats'         => $popular_ids,
			)
		);

		$data = ob_get_clean();

		$add = array(
			'what'     => $taxonomy->name,
			'id'       => $term_id,
			'data'     => str_replace( array( "n", "t" ), '', $data ),
			'position' => -1,
		);
	}

	$parent_dropdown_args = array(
		'taxonomy'         => $taxonomy->name,
		'hide_empty'       => 0,
		'name'             => 'new' . $taxonomy->name . '_parent',
		'orderby'          => 'name',
		'hierarchical'     => 1,
		'show_option_none' => '— ' . $taxonomy->labels->parent_item . ' —',
	);

	/** This filter is documented in wp-admin/includes/meta-boxes.php */
	$parent_dropdown_args = apply_filters( 'post_edit_category_parent_dropdown_args', $parent_dropdown_args );

	ob_start();

	wp_dropdown_categories( $parent_dropdown_args );

	$sup = ob_get_clean();

	$add['supplemental'] = array( 'newcat_parent' => $sup );

	$x = new WP_Ajax_Response( $add );
	$x->send();
}

Hooks

apply_filters( ‘post_edit_category_parent_dropdown_args’, array $parent_dropdown_args )

Filters the arguments for the taxonomy parent dropdown on the Post Edit page.

Changelog

Version Description
3.1.0 Introduced.