PHP script to sanitize HTML using wp_kses_post() except allow
<?php
$html = "...";
echo Allow_Youtube_Scripts::sanitize_html( $html );
class Allow_Youtube_Scripts {
static $allowed_protocols;
static function sanitize_html( $html ) {
if ( ! isset( self::$allowed_protocols ) ) {
self::$allowed_protocols = wp_allowed_protocols();
}
add_filter( 'wp_kses_allowed_html', $filter = array( __CLASS__, '_wp_kses_allowed_html' ), 10, 2 );
$html = wp_kses_post( $html );
$html = preg_replace_callback('#<script(.+?)>#', array( __CLASS__, '_strip_non_youtube_scripts' ), $html );
$html = preg_replace_callback('#<script.+?</script>?#ims', array( __CLASS__, '_strip_multiline_scripts' ), $html );
$html = str_replace( '<~script', '<script', $html );
remove_filter( 'wp_kses_allowed_html', $filter );
return $html;
}
static function _wp_kses_allowed_html($tags, $context) {
if ('post' === $context) {
$tags['script'] = array_fill_keys(array('src', 'type'), true);
}
return $tags;
}
static function _strip_multiline_scripts( $script ) {
return '';
}
static function _strip_non_youtube_scripts( $script ) {
$attributes = wp_kses_hair( $script[1], self::$allowed_protocols );
if ( empty( $attributes['src'] ) || ! preg_match( '#^https?://youtube.com/#', $attributes['src']['value'] ) ) {
$script = $script[0];
} else {
$script = '<~script';
foreach( array( 'src','type') as $attribute ) {
if ( ! empty( $attributes[ $attribute ] ) ) {
$script .= " {$attributes['src']['whole']}";
}
}
$script .= '>';
if ( empty( $script[2] ) ) {
$script .= '</script>';
}
}
return $script;
}
}