4

THE GOAL

I'm trying to parse a url and convert it to an embedded video player in my post's content but I think my regEx is off or I'm not creating a provider correctly.

THE CODE

Here is what I have setup now.

wp_embed_register_handler('brightcove', '/(players.brightcove.net/)([^/]+)/([^/]+)/index\.html\?videoId=([\d]+)/g', 'wp_embed_handler_brightcove');

function wp_embed_handler_brightcove($matches, $attr, $url, $rawattr) {

    // var_dump($matches, $attr, $url, $rawattr);

    $account  = esc_attr($matches[ 1 ]);
    $player   = esc_attr($matches[ 2 ]);
    $video_id = esc_attr($matches[ 3 ]);

    $embed = '<div style="display: block; position: relative; max-width: 142.86%;"><div style="padding-top: 39.3742%;"><iframe src="'
    . sprintf('http://players.brightcove.net/%1$s/%2$s/index.html?videoId=%3$s',
              $account,
              $player,
              $video_id
    ) . '" allowfullscreen="" webkitallowfullscreen="" mozallowfullscreen="" style="width: 100%; height: 100%; position: absolute; top: 0px; bottom: 0px; right: 0px; left: 0px;"></iframe></div></div>';

    return apply_filters('embed_brightcove', $embed, $matches, $attr, $url, $rawattr);
}

TESTING

$embed_code = wp_oembed_get('http://players.brightcove.net/1234567890123/default_default/index.html?videoId=1234567789012');

echo $embed_code; // nothing :(

I do have a regEx working on regexr which uses:

(players.brightcove.net/)([^/]+)/([^/]+)/index\.html\?videoId=([\d]+)

and looks for:

http://players.brightcove.net/{account}/{player_id}/index.html?videoId={video_Id}

RESOURCES

THE QUESTION

How can I get this custom embed handler to function correctly? Can I fix my regEx or am I not calling the methods correctly?


UPDATE: Experiment

I ran into VerbalExpressions a while ago and I wanted to see how this might work. The PHP version is here, but this is using the JS version that I can test on RegExr or RegEx101:

var tester = VerEx()
        .startOfLine()
        .maybe("http")
        .maybe("s")
        .maybe(":")
        .then("//players.brightcove.net/")
        .word()
        .then('/')
        .word()
        .then('/index.html?videoId=')
        .word()
        .maybe('&')
        .anythingBut(" ")
        .endOfLine();

Although it compiles down to something that works, it still needs some cleanup. Essential only making groups of the things I'm interested in and converting some orignal groups to non-matching groups.

// Before

/^(http)(s)?(\:\/\/players\.brightcove\.net\/)\w+(\/)\w+(\/index\.html\?videoId\=)\w+(\&)?([^\ ]*)$/gm

// After

/^(?:http)?(?:s)?(?:\:)?\/\/players\.brightcove\.net\/(\d+)\/(\w+)\/index\.html\?videoId\=(\d+)\&?[^\ ]*$/gm

UPDATE: SOLUTION

Modified slightly from @birgire's answer because account will always be numeric.

wp_embed_register_handler(
    'brightcove',
    '#https?://players\.brightcove\.net/([\d]+)/([^/]+)/index\.html\?videoId=([\d]+)#', 
    'wp_embed_handler_brightcove');
2

Just few notes here:

  • We have to be careful using % within sprintf() to avoid confusion with the placeholders. Try to remove the CSS styles.

  • It's sometimes easier to use the # or ~ delimiters in regular expressions, instead of the / delimiter.

  • Since you have the (players.brightcove.net/) as the first match, it might not match this assumption:

    $account  = esc_attr( $matches[1] );
    

    Try instead:

    #https?://players\.brightcove\.net/([^/]+)/([^/]+)/index\.html\?videoId=([\d]+)#
    

This seems to work in the content editor:

add_action( 'init', function()
{
    wp_embed_register_handler( 
       'brightcove', 
       '#https?://players\.brightcove\.net)/([^/]+)/([^/]+)/index.html\?videoId=([\d]+)#', 
       'wp_embed_handler_brightcove' 
    );
} );

where wp_embed_handler_brightcove() is the callback function defined by @jgraup above.

Here's a related answer I worked on recently.

Playing with PHPVerbalExpressions

@jgraup mentioned the library PHPVerbalExpressions - "PHP Regular expressions made easy".

Here's an attempt to use it:

$regex = new \VerbalExpressions\PHPVerbalExpressions\VerbalExpressions();

$regex->removeModifier( 'm' )
//      ->startOfLine()
      ->then( 'http' )
      ->maybe( 's' )
      ->then( '://players.brightcove.net/' )
      ->anythingBut( '/' )
      ->then( '/' )
      ->anythingBut( '/' )
      ->then( '/index.html?videoId=' )
      ->add( '([\d]+)' );
//      ->endOfLine();

This generates the following pattern:

/(?:http)(?:s)?(?:\:\/\/players\.brightcove\.net\/)(?:[^\/]*)(?:\/)(?:[^\/]*)(?:\/index\.html\?videoId\=)([\d]+)/

or if we expand it:

/
   (?:http)
   (?:s)?
   (?:\:\/\/players\.brightcove\.net\/)
   (?:[^\/]*)
   (?:\/)
   (?:[^\/]*)
   (?:\/index\.html\?videoId\=)
   ([\d]+)
/

We would have to adjust the matched keys accordingly with $matches.

  • 1
    ps: I don't think wp_oembed_get() is using any cache, so you might want to double check that further, I could be remembering that wrong so late. – birgire Jan 8 '16 at 1:56
  • I was only using it in the debug console but thanks for the heads up. – jgraup Jan 8 '16 at 1:57
  • ok sounds good ;-) – birgire Jan 8 '16 at 1:58
  • I forgot about this project but it might help in the future - github.com/VerbalExpressions/PHPVerbalExpressions – jgraup Jan 30 '16 at 5:37
  • 1
    Thanks for that link @jgraup - I attempted to use it here ;-) I didn't find a way to rewrite ([\d]+) other than using ->add( '([\d]+)' ). I wanted to rewrite this in the easy language, using e.g. ->range( 0,9 ) or even a second class instance to generate it, but that didn't work so well ;-) – birgire Jan 30 '16 at 11:33

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.