函数文档

wp_media_attach_action()

💡 云策文档标注

概述

wp_media_attach_action() 函数封装了媒体附件与文章之间的附加/分离操作逻辑,主要用于处理用户权限验证、数据库更新和钩子触发。

关键要点

  • 函数接受两个参数:$parent_id(必需,附件父级ID)和 $action(可选,默认为 'attach',接受 'attach' 或 'detach')。
  • 执行前检查用户是否具有编辑 $parent_id 和附件ID的权限,否则跳过或终止。
  • 根据 $action 值更新 wpdb->posts 表中的 post_parent 字段,实现附件附加或分离。
  • 操作完成后触发 wp_media_attach_action 钩子,清理附件缓存,并重定向到 upload.php 页面。

代码示例

function wp_media_attach_action( $parent_id, $action = 'attach' ) {
    global $wpdb;
    if ( ! $parent_id ) {
        return;
    }
    if ( ! current_user_can( 'edit_post', $parent_id ) ) {
        wp_die( __( 'Sorry, you are not allowed to edit this post.' ) );
    }
    $ids = array();
    foreach ( (array) $_REQUEST['media'] as $attachment_id ) {
        $attachment_id = (int) $attachment_id;
        if ( ! current_user_can( 'edit_post', $attachment_id ) ) {
            continue;
        }
        $ids[] = $attachment_id;
    }
    if ( ! empty( $ids ) ) {
        $ids_string = implode( ',', $ids );
        if ( 'attach' === $action ) {
            $result = $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->posts SET post_parent = %d WHERE post_type = 'attachment' AND ID IN ( $ids_string )", $parent_id ) );
        } else {
            $result = $wpdb->query( "UPDATE $wpdb->posts SET post_parent = 0 WHERE post_type = 'attachment' AND ID IN ( $ids_string )" );
        }
    }
    if ( isset( $result ) ) {
        foreach ( $ids as $attachment_id ) {
            do_action( 'wp_media_attach_action', $action, $attachment_id, $parent_id );
            clean_attachment_cache( $attachment_id );
        }
        $location = 'upload.php';
        $referer  = wp_get_referer();
        if ( $referer ) {
            if ( str_contains( $referer, 'upload.php' ) ) {
                $location = remove_query_arg( array( 'attached', 'detach' ), $referer );
            }
        }
        $key      = 'attach' === $action ? 'attached' : 'detach';
        $location = add_query_arg( array( $key => $result ), $location );
        wp_redirect( $location );
        exit;
    }
}

注意事项

  • 函数依赖于 $_REQUEST['media'] 数组来获取附件ID列表,需确保请求中包含此数据。
  • 使用 wpdb::prepare() 进行SQL查询参数化,以防止SQL注入风险。
  • 重定向前会清理查询参数,避免重复附加或分离操作。

📄 原文内容

Encapsulates the logic for Attach/Detach actions.

Parameters

$parent_idintrequired
Attachment parent ID.
$actionstringoptional
Attach/detach action. Accepts 'attach' or 'detach'.
Default 'attach'.

Source

function wp_media_attach_action( $parent_id, $action = 'attach' ) {
	global $wpdb;

	if ( ! $parent_id ) {
		return;
	}

	if ( ! current_user_can( 'edit_post', $parent_id ) ) {
		wp_die( __( 'Sorry, you are not allowed to edit this post.' ) );
	}

	$ids = array();

	foreach ( (array) $_REQUEST['media'] as $attachment_id ) {
		$attachment_id = (int) $attachment_id;

		if ( ! current_user_can( 'edit_post', $attachment_id ) ) {
			continue;
		}

		$ids[] = $attachment_id;
	}

	if ( ! empty( $ids ) ) {
		$ids_string = implode( ',', $ids );

		if ( 'attach' === $action ) {
			$result = $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->posts SET post_parent = %d WHERE post_type = 'attachment' AND ID IN ( $ids_string )", $parent_id ) );
		} else {
			$result = $wpdb->query( "UPDATE $wpdb->posts SET post_parent = 0 WHERE post_type = 'attachment' AND ID IN ( $ids_string )" );
		}
	}

	if ( isset( $result ) ) {
		foreach ( $ids as $attachment_id ) {
			/**
			 * Fires when media is attached or detached from a post.
			 *
			 * @since 5.5.0
			 *
			 * @param string $action        Attach/detach action. Accepts 'attach' or 'detach'.
			 * @param int    $attachment_id The attachment ID.
			 * @param int    $parent_id     Attachment parent ID.
			 */
			do_action( 'wp_media_attach_action', $action, $attachment_id, $parent_id );

			clean_attachment_cache( $attachment_id );
		}

		$location = 'upload.php';
		$referer  = wp_get_referer();

		if ( $referer ) {
			if ( str_contains( $referer, 'upload.php' ) ) {
				$location = remove_query_arg( array( 'attached', 'detach' ), $referer );
			}
		}

		$key      = 'attach' === $action ? 'attached' : 'detach';
		$location = add_query_arg( array( $key => $result ), $location );

		wp_redirect( $location );
		exit;
	}
}

Hooks

do_action( ‘wp_media_attach_action’, string $action, int $attachment_id, int $parent_id )

Fires when media is attached or detached from a post.

Changelog

Version Description
4.2.0 Introduced.