How to remove pingback from head?

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.

2 Answers
2

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;
}

Leave a Comment