3

I know this question has been asked and answered 1000 times. However, I've never truly found a solution that removes pingback link tag from "wp_head". While there are several ways to block xml-rcp/pingback/trackback from wordpress I'm trying to add to that by blocking it from the head

So basically I don't want this showing up in the rendered html:

Closest solution I've ever found was this:

add_filter( 'bloginfo_url', 'pmg_kt_kill_pingback_url', 10, 2 );
function pmg_kt_kill_pingback_url( $output, $show ) {
    if( $show == 'pingback_url' ) {
        $output = '';
    }
    return $output;
}

But it still shows up like this:

<link rel="pingback" href>

I know this isn't really a big deal, it was more annoying me than anything. I've been messing learning regex the past few days and I think I got the right patterns to remove pingback from the head.

The following two patterns remove all cases (from what I've tested of pingback):

/<link.*?rel=("|\')pingback("|\').*?href=("|\')(.*?)("|\')(.*?)?\/?>/i

/<link.*?href=("|\')(.*?)("|\').*?rel=("|\')pingback("|\')(.*?)?\/?>/i

I used the output buffer to achieve this:

if (!is_admin()) {      
        function link_rel_buffer_callback($buffer) {
            $buffer = preg_replace('/<link.*?rel=("|\')pingback("|\').*?href=("|\')(.*?)("|\')(.*?)?\/?>/i', '', $buffer);
            return $buffer;
        }
        function link_rel_buffer_start() {
            ob_start("link_rel_buffer_callback");
        }
        function link_rel_buffer_end() {
            ob_flush();
        }
        add_action('template_redirect', 'link_rel_buffer_start', -1);
        add_action('get_header', 'link_rel_buffer_start');
        add_action('wp_head', 'link_rel_buffer_end', 999);
    }

However if I try to combine the two regex patterns it doesn't work

if (!is_admin()) {      
        function link_rel_buffer_callback($buffer) {
            $buffer = preg_replace('/(?:<link.*?rel=("|\')pingback("|\').*?href=("|\')(.*?)("|\')(.*?)?\/?>|<link.*?href=("|\')(.*?)("|\').*?rel=("|\')pingback("|\')(.*?)?\/?>)/i', '', $buffer);
            return $buffer;
        }
        function link_rel_buffer_start() {
            ob_start("link_rel_buffer_callback");
        }
        function link_rel_buffer_end() {
            ob_flush();
        }
        add_action('template_redirect', 'link_rel_buffer_start', -1);
        add_action('get_header', 'link_rel_buffer_start');
        add_action('wp_head', 'link_rel_buffer_end', 999);
    }

I think the problem is I need to use preg_match. I tried checking with this and it worked:

function print_preg_match() {         
$pattern = '/(?:<link.*?rel=("|\')pingback("|\').*?href=("|\')(.*?)("|\')(.*?)?\/?>|<link.*?href=("|\')(.*?)("|\').*?rel=("|\')pingback("|\')(.*?)?\/?>)/i';
$subject = '<link rel="pingback" href="http://example.com/xmlrpc.php">';
if (preg_match($pattern, $subject, $matches)) {
   echo 'You Got A Match';
   }
}
add_action('all_admin_notices', 'print_preg_match');

However, I don't know how to use it correctly in this situation. This may be more of a stackoverflow question since it's dealing with regex, but i figured since it was specific to wordpress I put it up here.

5
  • Can't you just remove the pingback tag out of header.php? Commented Aug 21, 2014 at 19:49
  • That's what I do, just remove it from header.php.
    – gdaniel
    Commented Aug 21, 2014 at 20:21
  • That's not really the "WordPress" way :) Commented Aug 22, 2014 at 0:25
  • If it's a theme you didn't write yourself you would lose any changes with an update Commented Aug 22, 2014 at 0:27
  • Why don't you edit the theme? instead of adding pingback and then remove it...
    – user40422
    Commented May 7, 2015 at 9:41

2 Answers 2

4

Here's my improvement on it with less code for the same results:

add_action( 'plugins_loaded', 'wpse_158700_buffer' );

function wpse_158700_buffer() {
    # Enable output buffering
    ob_start( 'wpse_158700_pingback_url' );
}

function wpse_158700_pingback_url( $buffer ) {
    # If in the admin panel, don't run
    if ( is_admin() && ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX ) ) {
        return $buffer;
    }
    $buffer = preg_replace( '/(<link.*?rel=("|\')pingback("|\').*?href=("|\')(.*?)("|\')(.*?)?\/?>|<link.*?href=("|\')(.*?)("|\').*?rel=("|\')pingback("|\')(.*?)?\/?>)/i', '', $buffer );
    return $buffer;
}
3

It was just a mistake I had made, the above would work like this:

$buffer = preg_replace('/(<link.*?rel=("|\')pingback("|\').*?href=("|\')(.*?)("|\')(.*?)?\/?>|<link.*?href=("|\')(.*?)("|\').*?rel=("|\')pingback("|\')(.*?)?\/?>)/i', '', $buffer);

HERE is the revised answer:

if (!is_admin()) {      
    function link_rel_buffer_callback($buffer) {
        $buffer = preg_replace('/(<link.*?rel=("|\')pingback("|\').*?href=("|\')(.*?)("|\')(.*?)?\/?>|<link.*?href=("|\')(.*?)("|\').*?rel=("|\')pingback("|\')(.*?)?\/?>)/i', '', $buffer);
                return $buffer;
    }
    function link_rel_buffer_start() {
        ob_start("link_rel_buffer_callback");
    }
    function link_rel_buffer_end() {
        ob_flush();
    }
    add_action('template_redirect', 'link_rel_buffer_start', -1);
    add_action('get_header', 'link_rel_buffer_start');
    add_action('wp_head', 'link_rel_buffer_end', 999);
}


// Alternatively use this to just remove the url or use it together with the above
add_filter('bloginfo_url', function($output, $property){
    return ($property == 'pingback_url') ? null : $output;
}, 11, 2);

This removes pingback from the source code on your frontend programmatically.

While most developers include it in the header like this:

<link rel="pingback" href="<?php bloginfo( 'pingback_url' ); ?>" />

... there are many cases where it could be written and executed differently

Such as:

<link rel="pingback" href="http://www.example.com/xmlrpc.php" />
<link rel='pingback' href='http://example.com/xmlrpc.php' />
<link href='http://example.com/xmlrpc.php' rel='pingback'>

For a complete solution that blocks ALL functionality and access to XML-RPC pingback and trackback refer to this answer associated with the correct question. There have been many recent exploits to this file so it is wise to do this if you aren't using trackbacks/pingbacks:

Is There a Way to Completely Turn Off Pingbacks/Trackbacks?

4
  • 1
    Where are you calling the xmlrcp_blocked_htaccess function ? The xmlrpc.php file might be used for other things than pingbacks..
    – birgire
    Commented Nov 23, 2015 at 1:14
  • the regexp can be simplified as you know the pingback url from bloginfo('pingback_url') or such Commented Nov 23, 2015 at 5:48
  • Thanks @birgire for catching that. I fixed it and added it's working great now. I added the complete answer to the more appropriate question though (see link above). As for the xmlrcp.php being used elsewhere, it is required by very few plugins. However, my question here was for people who don't want it being used on their site. Mark, I definitely agree the regex could be shorten. I rarely use regex though and couldn't come up with anything shorter that would work. If you know of one I'd love to see it! Commented Nov 23, 2015 at 15:34
  • ps: I just mentioned the xmlrpc.php file for users using e.g. JetPack ;-)
    – birgire
    Commented Nov 23, 2015 at 15:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.