Skip to content

Instantly share code, notes, and snippets.

@mishterk
Created January 9, 2020 07:48
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mishterk/98aae3f2f8e41de844c9dca1404f2d57 to your computer and use it in GitHub Desktop.
Save mishterk/98aae3f2f8e41de844c9dca1404f2d57 to your computer and use it in GitHub Desktop.
Wraps oEmbed output in markup which we can then target with CSS for fluid responsiveness.
<?php
class ResponsiveOEmbeds {
/**
* Regex patterns for matching specific embeddable URLs
*
* @var array
*/
static $regex = array(
'youtube' => 'youtu\.?be(\.com)?\/',
'vimeo' => 'vimeo.com',
);
static function init() {
add_filter( 'embed_oembed_html', array( __CLASS__, 'make_embeds_responsive' ), 10, 4 );
}
/**
* Checks a given array of strings against the subject for regex match.
*
* @param array $possibles
* @param string $subject
*
* @return int Greater than 0 if match found
*/
static function preg_match_any( $possibles, $subject ) {
return preg_match( '/' . implode( '|', $possibles ) . '/', $subject );
}
/**
* Wraps all embeds (minus exceptions in regex) in responsive container
*
* [ &wmode=transparent ] parameter ensures youtube embeds don't sit at the highest z-index, interfering with modal overlays.
*
* @param $cache
* @param $url
* @param $attr
* @param $post_ID
*
* @return mixed|string
*/
static function make_embeds_responsive( $cache, $url, $attr, $post_ID ) {
$responsiveEmbeds = array(
self::$regex['youtube'],
self::$regex['vimeo'],
);
if ( self::preg_match_any( $responsiveEmbeds, $url ) ) {
if ( preg_match( '/' . self::$regex['youtube'] . '/', $url ) ) {
$cache = str_replace( 'feature=oembed', 'feature=oembed&rel=0&showinfo=0&showsearch=0&autohide=1&wmode=transparent', $cache );
}
$cache = self::wrap_responsive_embed( $cache );
}
return $cache;
}
/**
* Wraps embed in responsive markup
*
* By default, CSS is in place to treat the embed as having the standard 16:9 ratio common to YouTube and Vimeo embeds.
* Where necessary, a width and height can be passed to this method, allowing a different aspect ratio to be applied.
*
* @param string $embed The embed markup.
* @param null|int $width Optional width of embed.
* @param null|int $height Optional height of embed.
*
* @return string
*/
static function wrap_responsive_embed( $embed, $width = null, $height = null ) {
$style = '';
if ( $width and $height ) {
$bottomPadding = $height / $width * 100;
$style = "style=\"padding-bottom:{$bottomPadding}%\"";
}
//return '<div class="responsive-wrapper"' . $style . '>' . $embed . '</div>';
return "<div class=\"responsive-wrapper\" {$style}>{$embed}</div>";
}
/**
* Attempts to automatically handle wrapping of iframe tags by extracting the height and width attributes from the
* markup. If no height and width attributes are available, this allows
* \CTips\ResponsiveOEmbeds::wrap_responsive_embed() to run its default behaviour.
*
* @param string $iframe The iframe HTML string
*
* @return string
*/
static function wrap_responsive_iframe( $iframe ) {
$width = null;
$height = null;
preg_match_all( '/(width|height)="([0-9]+)"/', $iframe, $matches, PREG_SET_ORDER );
if ( count( $matches ) === 2 ) {
$width = $matches[0][2];
$height = $matches[1][2];
}
return self::wrap_responsive_embed( $iframe, $width, $height );
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment