do_enclose()
云策文档标注
概述
do_enclose() 函数用于检查文章内容中的视频和音频链接,并将其作为附件(enclosures)添加到文章元数据中。它通过比较现有附件和内容中的链接,自动管理附件的添加和移除,通常作为 pingbacks 和 trackbacks 的一部分调用。
关键要点
- 函数检查内容中的 URL,识别视频和音频链接,并添加为附件到 postmeta 表。
- 自动处理重复和无效链接:不会添加已存在的附件,并移除文章中不再存在的附件。
- 参数包括 $content(文章内容,可为 null 以使用 $post 的 post_content)和 $post(文章 ID 或 WP_Post 对象)。
- 返回 void(成功时)或 false(文章未找到时)。
- 使用 Hook:apply_filters('enclosure_links', $post_links, $post_id) 在查询数据库前过滤附件链接列表。
- 依赖多个 WordPress 核心函数,如 wp_extract_urls()、wp_get_http_headers() 和 add_post_meta()。
- 从版本 5.6.0 起,$content 参数不再可选,但传递 null 仍支持;5.3.0 引入参数可选性。
代码示例
function do_enclose( $content, $post ) {
global $wpdb;
require_once ABSPATH . WPINC . '/class-IXR.php';
$post = get_post( $post );
if ( ! $post ) {
return false;
}
if ( null === $content ) {
$content = $post->post_content;
}
$post_links = array();
$pung = get_enclosed( $post->ID );
$post_links_temp = wp_extract_urls( $content );
// 移除不再存在的附件
foreach ( $pung as $link_test ) {
if ( ! in_array( $link_test, $post_links_temp, true ) ) {
$mids = $wpdb->get_col( $wpdb->prepare( "SELECT meta_id FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = 'enclosure' AND meta_value LIKE %s", $post->ID, $wpdb->esc_like( $link_test ) . '%' ) );
foreach ( $mids as $mid ) {
delete_metadata_by_mid( 'post', $mid );
}
}
}
// 添加新附件
foreach ( (array) $post_links_temp as $link_test ) {
if ( ! in_array( $link_test, $pung, true ) ) {
$test = parse_url( $link_test );
if ( false === $test ) {
continue;
}
if ( isset( $test['query'] ) ) {
$post_links[] = $link_test;
} elseif ( isset( $test['path'] ) && ( '/' !== $test['path'] ) && ( '' !== $test['path'] ) ) {
$post_links[] = $link_test;
}
}
}
$post_links = apply_filters( 'enclosure_links', $post_links, $post->ID );
foreach ( (array) $post_links as $url ) {
$url = strip_fragment_from_url( $url );
if ( '' !== $url && ! $wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = 'enclosure' AND meta_value LIKE %s", $post->ID, $wpdb->esc_like( $url ) . '%' ) ) ) {
$headers = wp_get_http_headers( $url );
if ( $headers ) {
$len = isset( $headers['Content-Length'] ) ? (int) $headers['Content-Length'] : 0;
$type = isset( $headers['Content-Type'] ) ? $headers['Content-Type'] : '';
$allowed_types = array( 'video', 'audio' );
$url_parts = parse_url( $url );
if ( false !== $url_parts && ! empty( $url_parts['path'] ) ) {
$extension = pathinfo( $url_parts['path'], PATHINFO_EXTENSION );
if ( ! empty( $extension ) ) {
foreach ( wp_get_mime_types() as $exts => $mime ) {
if ( preg_match( '!^(' . $exts . ')$!i', $extension ) ) {
$type = $mime;
break;
}
}
}
}
if ( in_array( substr( $type, 0, strpos( $type, '/' ) ), $allowed_types, true ) ) {
add_post_meta( $post->ID, 'enclosure', "$urln$lenn$mimen" );
}
}
}
}
}注意事项
- 函数内部包含调试代码,可能需要整理和优化。
- 依赖全局变量 $wpdb 进行数据库操作,确保在调用前已正确初始化。
- 使用 apply_filters('enclosure_links', ...) 允许开发者自定义附件链接列表。
- 从版本 5.6.0 开始,$content 参数必须提供,但传递 null 可跳过使用默认内容。
原文内容
Checks content for video and audio links to add as enclosures.
Description
Will not add enclosures that have already been added and will remove enclosures that are no longer in the post. This is called as pingbacks and trackbacks.
Parameters
$contentstring|nullrequired-
Post content. If
null, thepost_contentfield from$postis used. $postint|WP_Postrequired-
Post ID or post object.
Source
function do_enclose( $content, $post ) {
global $wpdb;
// @todo Tidy this code and make the debug code optional.
require_once ABSPATH . WPINC . '/class-IXR.php';
$post = get_post( $post );
if ( ! $post ) {
return false;
}
if ( null === $content ) {
$content = $post->post_content;
}
$post_links = array();
$pung = get_enclosed( $post->ID );
$post_links_temp = wp_extract_urls( $content );
foreach ( $pung as $link_test ) {
// Link is no longer in post.
if ( ! in_array( $link_test, $post_links_temp, true ) ) {
$mids = $wpdb->get_col( $wpdb->prepare( "SELECT meta_id FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = 'enclosure' AND meta_value LIKE %s", $post->ID, $wpdb->esc_like( $link_test ) . '%' ) );
foreach ( $mids as $mid ) {
delete_metadata_by_mid( 'post', $mid );
}
}
}
foreach ( (array) $post_links_temp as $link_test ) {
// If we haven't pung it already.
if ( ! in_array( $link_test, $pung, true ) ) {
$test = parse_url( $link_test );
if ( false === $test ) {
continue;
}
if ( isset( $test['query'] ) ) {
$post_links[] = $link_test;
} elseif ( isset( $test['path'] ) && ( '/' !== $test['path'] ) && ( '' !== $test['path'] ) ) {
$post_links[] = $link_test;
}
}
}
/**
* Filters the list of enclosure links before querying the database.
*
* Allows for the addition and/or removal of potential enclosures to save
* to postmeta before checking the database for existing enclosures.
*
* @since 4.4.0
*
* @param string[] $post_links An array of enclosure links.
* @param int $post_id Post ID.
*/
$post_links = apply_filters( 'enclosure_links', $post_links, $post->ID );
foreach ( (array) $post_links as $url ) {
$url = strip_fragment_from_url( $url );
if ( '' !== $url && ! $wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = 'enclosure' AND meta_value LIKE %s", $post->ID, $wpdb->esc_like( $url ) . '%' ) ) ) {
$headers = wp_get_http_headers( $url );
if ( $headers ) {
$len = isset( $headers['Content-Length'] ) ? (int) $headers['Content-Length'] : 0;
$type = isset( $headers['Content-Type'] ) ? $headers['Content-Type'] : '';
$allowed_types = array( 'video', 'audio' );
// Check to see if we can figure out the mime type from the extension.
$url_parts = parse_url( $url );
if ( false !== $url_parts && ! empty( $url_parts['path'] ) ) {
$extension = pathinfo( $url_parts['path'], PATHINFO_EXTENSION );
if ( ! empty( $extension ) ) {
foreach ( wp_get_mime_types() as $exts => $mime ) {
if ( preg_match( '!^(' . $exts . ')$!i', $extension ) ) {
$type = $mime;
break;
}
}
}
}
if ( in_array( substr( $type, 0, strpos( $type, '/' ) ), $allowed_types, true ) ) {
add_post_meta( $post->ID, 'enclosure', "$urln$lenn$mimen" );
}
}
}
}
}
Hooks
- apply_filters( ‘enclosure_links’, string[] $post_links, int $post_id )
-
Filters the list of enclosure links before querying the database.