0

I'm trying to create a shortcode that will search within some specified text for a link and replace it with one that I specify. For example:

[scode]Click on <a href="www.X.com">this link</a>[scode]
[scode]Click on <a href="www.Y.com">this link</a>[scode]

...will both be changed to:

[scode]Click on <a href="www.Z.com">this link</a>[scode]

I'm trying to put together a function that will search for links and replace them with the one that I specify. Here's what I have right now:

// Adds [hide] shortcode for hiding content from non-registered users.

function hide_text( $atts,$content) {
    if ( is_user_logged_in () ) {
        return $content;
    }
    else {
        $pattern = '(?<=href=("|\'))[^"\']+(?=("|\'))';
        $newurl = "http://replacementurl.com";
        $content = preg_replace($pattern,$newurl,$content);
        echo $content;
          }
    }
add_shortcode( 'hide', 'hide_text' );

This just crashes the site, though. I'm not a PHP expert (much less an expert on regex), but are there at least any glaring irregularities in my code?

Or perhaps there's just a better way to go about this and I'm making it way more complicated than it needs to be?

UPDATE:

As suggested, I turned on debug log, which showed me that I had an extra } in the code. Updated code is shown above. Now the site isn't crashing, but the link and text within the shortcode is completely erased, just blank.

9
  • 1
    enable debugging to see errors. the one thing that stands out immediately is the quotes in your pattern.
    – Milo
    Sep 11 '13 at 20:47
  • There should also be a ; at the end of the $newurl line.
    – Pat J
    Sep 11 '13 at 20:51
  • Yep, had the ; in there, sorry. Sep 11 '13 at 20:52
  • @Milo debug log showed that there was an extra } in there. I removed it, but now the link (and the text) is missing entirely, just a blank space. Will update answer. Sep 11 '13 at 20:53
  • you shouldn"t use a shortcode for that. Use a filter in your functions.php, that filters out the related content. see: codex.wordpress.org/Plugin_API/Filter_Reference/the_content
    – pixeline
    Sep 11 '13 at 21:02
2

Your shortcode function should look like this:

function replace_url_for_nonlogged( $atts, $content = "") {
  if ( is_user_logged_in () ) return $content;
  extract( shortcode_atts( array(
    'replace' => 'http://www.default_replace_url.com',
  ), $atts ) );
  $pattern = '/href=("|\')((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)("|\')/';
  return preg_replace($pattern, "href=\"$replace\"", $content);
}
add_shortcode( 'scode', 'replace_url_for_nonlogged' );

Then you can use the shortcode like this:

[scode]Lorem <a href="http://reservedurl.com">ipsum</a> dolor <a href='http://resersinglequoted.com'>simet</a>.[/scode]

and the output became:

Lorem <a href="http://www.default_replace_url.com">ipsum</a> dolor <a href="http://www.default_replace_url.com">simet</a>.

the url replaced is setted as default in the replace_url_for_nonlogged function.

If you want you can pass the replacent url via shortcode att, e.g.

[scode replace="http://www.google.com"]Lorem <a href="http://reservedurl.com">ipsum</a> dolor <a href='http://resersinglequoted.com'>simet</a>.[/scode]

and this time the output became:

Lorem <a href="http://www.google.com">ipsum</a> dolor <a href="http://www.google.com">simet</a>.

enter image description here

2
  • Did you test this? It's not changing the link for me... Sep 12 '13 at 1:21
  • 1
    @TimMcClure are you sure that when you test you are not logged in? I've tested, and it works for me. See the added screenshot on answer.
    – gmazzap
    Sep 12 '13 at 2:08
0

Try this:

function timMcLure_hide_text( $atts,$content="") {
    if (!is_user_logged_in () ) {
      $pattern = "<a\s[^>]*href=(\"??)([^\" >]*?)\\1[^>]*>(.*)<\/a>";
      $newurl = "http://replacementurl.com";
      $content = preg_replace($pattern, $newurl, $content);
    }
    return $content;
}
add_shortcode( 'urlhide', 'timMcLure_hide_text' );

Then use [urlhide]as a shortcode.

Please try and report as i cannot easily test this.

2
  • This deletes all content within the shortcode. Aren't you making $content empty in the first line? Sep 12 '13 at 1:23
  • no, i'm telling the function that $content's default value is empty.
    – pixeline
    Sep 12 '13 at 12:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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