String regex match replace for role ‘contributor’ only

currently I’m using the below code to add rel=nofollow and target=_blank to all external links of my site’s content but I would like this to happen only on Contributors posts. IE, Authors posts and above have no rewrite rules.

<?php

add_filter( 'the_content', 'cn_nf_url_parse');

function cn_nf_url_parse( $content ) {

$regexp = "<as[^>]*href=("??)([^" >]*?)\1[^>]*>";
if(preg_match_all("/$regexp/siU", $content, $matches, PREG_SET_ORDER)) {
    if( !empty($matches) ) {

        $srcUrl = get_option('siteurl');
        for ($i=0; $i < count($matches); $i++)
        {

            $tag = $matches[$i][0];
            $tag2 = $matches[$i][0];
            $url = $matches[$i][0];

            $noFollow = '';

            $pattern = '/targets*=s*"s*_blanks*"/';
            preg_match($pattern, $tag2, $match, PREG_OFFSET_CAPTURE);
            if( count($match) < 1 )
                $noFollow .= ' target="_blank" ';

            $pattern = '/rels*=s*"s*[n|d]ofollows*"/';
            preg_match($pattern, $tag2, $match, PREG_OFFSET_CAPTURE);
            if( count($match) < 1 )
                $noFollow .= ' rel="nofollow" ';

            $pos = strpos($url,$srcUrl);
            if ($pos === false) {
                $tag = rtrim ($tag,'>');
                $tag .= $noFollow.'>';
                $content = str_replace($tag2,$tag,$content);
            }
        }
    }
}

$content = str_replace(']]>', ']]&gt;', $content);
return $content;

}

Related posts

1 comment

  1. There’s author_can() for that:

    add_action( 'loop_start', 'wpse105294_nofollow_author' );
    function wpse105294_nofollow_author()
    {
        ! author_can( $GLOBALS['post']->ID, 'edit_others_posts' )
            AND add_filter( 'the_content', 'cn_nf_url_parse');
    }
    

    So you only add that filter callback for authors and other roles that don’t have the possibility to edit_others_posts. By default this is Subscriber and Author. For more info, take a look at the Codex article about Roles and Capabilities.

    Edit

    As I’ve lately done some stuff with the PHP HTML DOM Parser, I thought it might be better to use this one. For the easiness off things the code was mostly taken from @Alex answer on SO.

    add_filter( 'the_content', 'cn_nf_url_parse');
    function wpse_105294_Content_Parser( $content )
    {
        $dom = new DOMDocument;
        $dom->loadHTML( $content );
    
        // DOMXPath() might be just too much
        $anchors = $dom->getElementByTagName( 'a' );
    
        foreach ( $anchors as $a )
        {
            if ( 
                ! $a->hasAttribute( 'rel' )
                OR '' === ( $rel = trim( $a->getAttribute( 'rel' ) ) )
            )
                continue;
    
            $rel = preg_split( '/s+/', $rel );
    
            if ( in_array( 'nofollow', $rel ) )
               continue;
    
            $rel[] = 'nofollow';
            $anchor->setAttribute( 'rel', implode( ' ', $rel ) );
        }
    
        $html = '';
    
        // Remove `htmlbody` before returning
        foreach ( $dom->getElementsByTagName( 'body' )->item(0)->childNodes as $el )
            $html .= $dom->saveXML( $el, LIBXML_NOEMPTYTAG );
    
        return $html;
    }
    

Comments are closed.