pingback()
云策文档标注
概述
pingback() 函数用于向文章中发现的链接发送 pingback 通知。它接受文章内容和文章对象作为参数,处理链接并返回 pingback 状态数组。
关键要点
- 函数参数:$content(字符串,必需,文章内容,若为空则从文章中获取)和 $post(整数或 WP_Post 对象,必需,文章 ID 或对象)。
- 返回值:一个数组,键为链接,值为布尔值,表示 pingback 状态。
- 处理流程:提取文章中的 URL,过滤掉已 ping 过的链接、自身链接和本地附件,然后通过 RPC 调用发送 pingback。
- 相关 Hook:包括 pre_ping 动作和 pingback_useragent 过滤器,用于在发送前修改链接或用户代理。
- 依赖函数:如 wp_extract_urls()、get_pung()、discover_pingback_server_uri() 等,用于辅助处理。
代码示例
function pingback( $content, $post ) {
require_once ABSPATH . WPINC . '/class-IXR.php';
require_once ABSPATH . WPINC . '/class-wp-http-ixr-client.php';
$post_links = array();
$post = get_post( $post );
if ( ! $post ) {
return array();
}
$pung = get_pung( $post );
if ( empty( $content ) ) {
$content = $post->post_content;
}
$post_links_temp = wp_extract_urls( $content );
$ping_status = array();
foreach ( (array) $post_links_temp as $link_test ) {
if ( ! in_array( $link_test, $pung, true ) && ( url_to_postid( $link_test ) !== $post->ID ) && ! is_local_attachment( $link_test ) ) {
$test = parse_url( $link_test );
if ( $test ) {
if ( isset( $test['query'] ) ) {
$post_links[] = $link_test;
} elseif ( isset( $test['path'] ) && ( '/' !== $test['path'] ) && ( '' !== $test['path'] ) ) {
$post_links[] = $link_test;
}
}
}
}
$post_links = array_unique( $post_links );
do_action_ref_array( 'pre_ping', array( &$post_links, &$pung, $post->ID ) );
foreach ( (array) $post_links as $pagelinkedto ) {
$pingback_server_url = discover_pingback_server_uri( $pagelinkedto );
if ( $pingback_server_url ) {
if ( function_exists( 'set_time_limit' ) ) {
set_time_limit( 60 );
}
$pagelinkedfrom = get_permalink( $post );
$client = new WP_HTTP_IXR_Client( $pingback_server_url );
$client->timeout = 3;
$client->useragent = apply_filters( 'pingback_useragent', $client->useragent . ' -- WordPress/' . get_bloginfo( 'version' ), $client->useragent, $pingback_server_url, $pagelinkedto, $pagelinkedfrom );
$client->debug = false;
$status = $client->query( 'pingback.ping', $pagelinkedfrom, $pagelinkedto );
if ( $status || ( isset( $client->error->code ) && 48 === $client->error->code ) ) {
add_ping( $post, $pagelinkedto );
}
$ping_status[$pagelinkedto] = $status;
}
}
return $ping_status;
}注意事项
- 函数在发送 pingback 前会触发 pre_ping 动作,允许开发者修改链接列表。
- 使用 pingback_useragent 过滤器可以自定义发送 pingback 时的用户代理字符串。
- 函数会跳过已 ping 过的链接、指向自身的链接和本地附件链接,避免重复或无效通知。
- 从 WordPress 6.8.0 开始,返回值改为按链接索引的 pingback 状态数组,便于跟踪每个链接的结果。
原文内容
Pings back the links found in a post.
Parameters
$contentstringrequired-
Post content to check for links. If empty will retrieve from post.
$postint|WP_Postrequired-
Post ID or object.
Source
function pingback( $content, $post ) {
require_once ABSPATH . WPINC . '/class-IXR.php';
require_once ABSPATH . WPINC . '/class-wp-http-ixr-client.php';
// Original code by Mort (http://mort.mine.nu:8080).
$post_links = array();
$post = get_post( $post );
if ( ! $post ) {
return array();
}
$pung = get_pung( $post );
if ( empty( $content ) ) {
$content = $post->post_content;
}
/*
* Step 1.
* Parsing the post, external links (if any) are stored in the $post_links array.
*/
$post_links_temp = wp_extract_urls( $content );
$ping_status = array();
/*
* Step 2.
* Walking through the links array.
* First we get rid of links pointing to sites, not to specific files.
* Example:
* http://dummy-weblog.org
* http://dummy-weblog.org/
* http://dummy-weblog.org/post.php
* We don't wanna ping first and second types, even if they have a valid <link/>.
*/
foreach ( (array) $post_links_temp as $link_test ) {
// If we haven't pung it already and it isn't a link to itself.
if ( ! in_array( $link_test, $pung, true ) && ( url_to_postid( $link_test ) !== $post->ID )
// Also, let's never ping local attachments.
&& ! is_local_attachment( $link_test )
) {
$test = parse_url( $link_test );
if ( $test ) {
if ( isset( $test['query'] ) ) {
$post_links[] = $link_test;
} elseif ( isset( $test['path'] ) && ( '/' !== $test['path'] ) && ( '' !== $test['path'] ) ) {
$post_links[] = $link_test;
}
}
}
}
$post_links = array_unique( $post_links );
/**
* Fires just before pinging back links found in a post.
*
* @since 2.0.0
*
* @param string[] $post_links Array of link URLs to be checked (passed by reference).
* @param string[] $pung Array of link URLs already pinged (passed by reference).
* @param int $post_id The post ID.
*/
do_action_ref_array( 'pre_ping', array( &$post_links, &$pung, $post->ID ) );
foreach ( (array) $post_links as $pagelinkedto ) {
$pingback_server_url = discover_pingback_server_uri( $pagelinkedto );
if ( $pingback_server_url ) {
// Allow an additional 60 seconds for each pingback to complete.
if ( function_exists( 'set_time_limit' ) ) {
set_time_limit( 60 );
}
// Now, the RPC call.
$pagelinkedfrom = get_permalink( $post );
// Using a timeout of 3 seconds should be enough to cover slow servers.
$client = new WP_HTTP_IXR_Client( $pingback_server_url );
$client->timeout = 3;
/**
* Filters the user agent sent when pinging-back a URL.
*
* @since 2.9.0
*
* @param string $concat_useragent The user agent concatenated with ' -- WordPress/'
* and the WordPress version.
* @param string $useragent The useragent.
* @param string $pingback_server_url The server URL being linked to.
* @param string $pagelinkedto URL of page linked to.
* @param string $pagelinkedfrom URL of page linked from.
*/
$client->useragent = apply_filters( 'pingback_useragent', $client->useragent . ' -- WordPress/' . get_bloginfo( 'version' ), $client->useragent, $pingback_server_url, $pagelinkedto, $pagelinkedfrom );
// When set to true, this outputs debug messages by itself.
$client->debug = false;
$status = $client->query( 'pingback.ping', $pagelinkedfrom, $pagelinkedto );
if ( $status // Ping registered.
|| ( isset( $client->error->code ) && 48 === $client->error->code ) // Already registered.
) {
add_ping( $post, $pagelinkedto );
}
$ping_status[ $pagelinkedto ] = $status;
}
}
return $ping_status;
}
Hooks
- apply_filters( ‘pingback_useragent’, string $concat_useragent, string $useragent, string $pingback_server_url, string $pagelinkedto, string $pagelinkedfrom )
-
Filters the user agent sent when pinging-back a URL.
- do_action_ref_array( ‘pre_ping’, string[] $post_links, string[] $pung, int $post_id )
-
Fires just before pinging back links found in a post.