Disable External Pingacks on WordPress Posts and Only Allow 'Self Pings'

I use wordpress for my Social Media site. WordPress Pings allow other blog posts to appear in comments when they link to us.

I want to limit it to only blog posts created on my own site. Basically I only want SELF-PINGS/Trackbacks.

If Other site tries to send ping reject it then and their, but if my own site https://milyin.com's post tries to send a ping readily accept it and show it in comment section.

I tried, wp-admin - discussion - (unselect) Allow links from other blog posts.

But that disables internal Pings too. Secondly My authors are able to turn on/off the pingbacks for each post. So, many of the posts still recieve external pings.

Here's a screenshot of the same: https://snipboard.io/8lVIrE.jpg

I tried to do some code.

I found a tutorial from How Disable Self Pingbacks in WordPress

And I tried to modify it to fit my needs

function SelfPing( $links ) {
    $Home = get_option( 'home' );
    foreach ( $links as $l = $link ){
        if ( strpos( $link, $Home )  === false){
            unset($links[$l]);
        }
    }
}
add_action( 'pre_ping', 'SelfPing' );

However this didn't solve the purpose.

I still recieve pings from all sorts of sites, on my posts, as majority of my authors manually turn on Pings.

So How can I have only self pings, and remove external pings, even when my authors manually turn on pings for all posts.

Topic functions php pingbacks plugin-development posts Wordpress

Category Web


If you don't make any other use of XMLRPC service in WordPress than the pingbacks/trackbacks, you could try limiting requests to xmlrpc.php file only for requests from your own server by adding this to your .htaccess file

<Files xmlrpc.php>
    Order deny,allow
    Deny from all
    Allow from 127.0.0.1
</Files>

This would work only if your webserver is Apache and it's configured to read local .htaccess files of overriding it's main configuration. Nginx, Litespeed and others don't use .htaccess files whatsoever, so no point in trying this with them.

Edit:

If you are using xmlrpc.php for other stuff too, you could use the xmlrpc_call hook in order to check if the call is a pingback and if it's from the right address (localhost). Here's how it should look (in theory):

add_action( 'xmlrpc_call', 'limit_to_local_pingbacks', 10, 3 );
function limit_to_local_pingbacks( string $type_of_call, array|string $args, wp_xmlrpc_server $server ) {
    if ( 'pingback.ping' !== $type_of_call ) {
        return;
    }
    if ( '127.0.0.1' !== $_SERVER['REMOTE_ADDR'] ) {
        wp_die();
    }

}

If you want to receive only linkbacks from your own WordPress site, then try both of these:

But if you want to allow all that were sent as trackbacks (where the comment type is trackback), then just ignore the second snippet below, which I added because in default/core themes like Twenty Twenty-One, both pingbacks and trackbacks would each appear as a "Pingback" in the post's comments section.

  1. This uses the xmlrpc_call action to disable pingbacks sent via the XML-RPC method:

    add_action( 'xmlrpc_call', 'disallow_external_xmlrpc_pingback', 10, 3 );
    function disallow_external_xmlrpc_pingback( $name, $args, $server ) {
        if ( 'pingback.ping' == $name && false === strpos( $args[0], home_url() ) ) {
            // Exit with a proper error.
            $server->error( new IXR_Error( 0, 'Sorry, trackbacks from remote sites are not allowed.' ) );
        }
    }
    
  2. This uses the pre_trackback_post action to disable trackbacks sent via the standard HTTP POST method (i.e. not using XML-RPC):

    add_action( 'pre_trackback_post', 'disallow_external_POST_trackback', 10, 2 );
    function disallow_external_POST_trackback( $tb_id, $tb_url ) {
        if ( false === strpos( $tb_url, home_url() ) ) {
            // Exit with a proper error.
            trackback_response( 1, 'Sorry, trackbacks from remote sites are not allowed.' );
        }
    }
    

And BTW, in the code in the question, $home is undefined and it should be $Home ( note the uppercase "H" and see this which says, "variable name is case-sensitive" :) ).

About

Geeks Mental is a community that publishes articles and tutorials about Web, Android, Data Science, new techniques and Linux security.