0
votes

Due to some minor bugs with the SoundCloud Shortcode plugin when served over HTTPS, I would like to run a Regex search & replace over my Wordpress blog. I'm sorted with with ways to do that in general, but I'm looking for a Regex pattern prepared for some eventualities.

When I manually grab the iframe embed code from the following shortcode…

[soundcloud url="http://api.soundcloud.com/tracks/58082404" params="auto_play=false&show_artwork=false&color=372f2d" width="100%" height="166" iframe="true" /]

…it turns into something like this:

<iframe width="100%" height="400" scrolling="no" frameborder="no" src="https://w.soundcloud.com/player/?visual=true&url=http%3A%2F%2Fapi.soundcloud.com%2Ftracks%2F58082404&show_artwork=true"></iframe>

You might notice that the sizes vary and that some of the parameters won't be passed. I will have to deal with this one way or another, but for now I'm looking for a way to convert the shortcode into an iframe with all of the original parameters. One of the problems is, that I cannot be sure that all the parameters are available in the shortcode and that the order these are passed could differ.

[soundcloud url="…"]
[soundcloud url="…" width="…" height="…"]
[soundcloud width="…" height="…" url="…" params="…"]
[soundcloud height="…" width="…" params="…" url="…"]

I am looking for a Regex pattern that makes sure that any of these gets converted into embed code for the iframe player.

<iframe width="WIDTH" height="HEIGHT" src="URL&PARAMS"></iframe>

Can anyone provide a working Regex pattern to do this?

1
Take a look at the source: core.trac.wordpress.org/browser/tags/3.9/src/wp-includes/…, here you find the logical methods for shortcodes. You can use the methods in your own filters (for example the_content). Best function for you: shortcode_parse_atts($text) - Adrian Preuss

1 Answers

0
votes

Not tested, but see the methods. Copied the do_shortcode_tag and do_shortcode to attach on a new the_content filter:

<?php
    // Priority "10", do_shortcode has "11" and we would like parse that BEFORE the shortcodes will be handled...
    add_filter('the_content', 'replaceHTTPS', 10);

    function replaceHTTPS($content) {
        global $shortcode_tags;

        // Check if the content has shortcodes
        if(strpos($content, '[') === false) {
            return $content;
        }

        if(empty($shortcode_tags) || !is_array($shortcode_tags)) {
            return $content;
        }

        // Get the Rexex to find shortcodes
        $pattern = get_shortcode_regex();

        // Replace the stuff
        return preg_replace_callback("/$pattern/s", 'replaceHTTPS_Callback', $content);
    }

    function replaceHTTPS_Callback($matches) {
        global $shortcode_tags;

        // allow [[foo]] syntax for escaping a tag
        if($matches[1] == '[' && $matches[6] == ']') {
            return substr($matches[0], 1, -1);
        }

        $tag    = $matches[2];
        $attr   = shortcode_parse_atts($matches[3]);

        // LETS Start your own logical experiment!
        // Check if the shortcode is "soundcloud"
        if($tag == 'soundcloud') {
            // check all entrys
            if(isset($attr) && count($attr) > 0) {
                foreach($attr AS $name => $value) {
                    // When Attribute "url"
                    if(strtolower($name) == 'url') {
                        // And when starts with "http://"
                        $test = 'http://';
                        if(substr($value, 0, strlen($test) == $test) {
                            // Than replace it,..
                            $attr[$name] = str_replace($test, 'https://', $value);
                        }
                    }
                }
            }
        }

        // enclosing tag - extra parameter
        if(isset($matches[5])) {
            return $matches[1] . call_user_func($shortcode_tags[$tag], $attr, $matches[5], $tag) . $matches[6];

        // self-closing tag
        } else {
            return $matches[1] . call_user_func($shortcode_tags[$tag], $attr, null,  $tag) . $matches[6];
        }
    }