web-dev-qa-db-ja.com

投稿から最初の動画を取得する(埋め込みと動画の両方のショートコード)

目標は、投稿から最初のビデオ(埋め込みまたはショートコード)を取得することです。そのため、投稿コンテンツに埋め込みビデオ(WPでサポート)または[video]ショートコードがあるかどうかを確認する必要があります。 1つの投稿に複数の動画と埋め込みが存在する可能性があります。見つかった場合 - 一致する特定のパターンの順序には依存しませんが、投稿に挿入された順序に従って、最初のものを返します。

これが私のこれまでの進歩です...

これは最初の[video]ショートコードを返します。動画のショートコードだけでなく、埋め込みも検索する方法はありますか?

function theme_self_hosted_videos() {
global $post;
$pattern = get_shortcode_regex();
  if ( preg_match_all( '/'. $pattern .'/s', $post->post_content, $matches ) && array_key_exists( 2, $matches ) && in_array( 'video', $matches[2] ) ) {
    $videos = $matches[0];
    $i = 0;
    foreach ($videos as $video ) {
        if($i == 0) {
            echo do_shortcode($video);
        }
        $i++;
    }
  }
  return false;
}
add_action( 'wp', 'theme_self_hosted_videos' );

これが、投稿から埋め込まれた最初のビデオを返す機能の現在の進歩です。ただし、期待どおりに動作しません。明らかに$ pattern_arrayの順番に依存していますし、おそらくパターン自体にも依存しています...

function theme_oembed_videos() {

global $post;

// Here is a sample array of patterns for supported video embeds from wp-includes/class-wp-embed.php
$pattern_array = array(
    '#https://youtu\.be/.*#i',
    '#https://(www\.)?youtube\.com/playlist.*#i',
    '#https://(www\.)?youtube\.com/watch.*#i',
    '#http://(www\.)?youtube\.com/watch.*#i',
    '#http://(www\.)?youtube\.com/playlist.*#i',
    '#http://youtu\.be/.*#i',
    '#https?://wordpress.tv/.*#i',
    '#https?://(.+\.)?vimeo\.com/.*#i'
);

foreach ($pattern_array as $pattern) {

    if (preg_match_all($pattern, $post->post_content, $matches)) {
        return wp_oembed_get( $matches[0] );
    }
    return false;

}

}
6
Nikita

あなたは一つの大きな正規表現ですべてのパターンを一緒にマッシュすることを試みることができ、そして内容の単純な行ごとの解析をすることができます:

function theme_oembed_videos() {

    global $post;

    if ( $post && $post->post_content ) {

        global $shortcode_tags;
        // Make a copy of global shortcode tags - we'll temporarily overwrite it.
        $theme_shortcode_tags = $shortcode_tags;

        // The shortcodes we're interested in.
        $shortcode_tags = array(
            'video' => $theme_shortcode_tags['video'],
            'embed' => $theme_shortcode_tags['embed']
        );
        // Get the absurd shortcode regexp.
        $video_regex = '#' . get_shortcode_regex() . '#i';

        // Restore global shortcode tags.
        $shortcode_tags = $theme_shortcode_tags;

        $pattern_array = array( $video_regex );

        // Get the patterns from the embed object.
        if ( ! function_exists( '_wp_oembed_get_object' ) ) {
            include ABSPATH . WPINC . '/class-oembed.php';
        }
        $oembed = _wp_oembed_get_object();
        $pattern_array = array_merge( $pattern_array, array_keys( $oembed->providers ) );

        // Or all the patterns together.
        $pattern = '#(' . array_reduce( $pattern_array, function ( $carry, $item ) {
            if ( strpos( $item, '#' ) === 0 ) {
                // Assuming '#...#i' regexps.
                $item = substr( $item, 1, -2 );
            } else {
                // Assuming glob patterns.
                $item = str_replace( '*', '(.+)', $item );
            }
            return $carry ? $carry . ')|('  . $item : $item;
        } ) . ')#is';

        // Simplistic parse of content line by line.
        $lines = explode( "\n", $post->post_content );
        foreach ( $lines as $line ) {
            $line = trim( $line );
            if ( preg_match( $pattern, $line, $matches ) ) {
                if ( strpos( $matches[0], '[' ) === 0 ) {
                    $ret = do_shortcode( $matches[0] );
                } else {
                    $ret = wp_oembed_get( $matches[0] );
                }
                return $ret;
            }
        }
    }
}

また、埋め込みにトランジェントを使用したい場合があります - 私が与えた この回答 を参照してください。

2
bonger

ショートコードと埋め込みメディアの両方に get_media_embedded_in_content() 関数を使うことができます(それはこれらのHTMLタグを探します:オーディオ、ビデオ、オブジェクト、埋め込み、またはiframe)、適用されたフィルタとショートコードを実行したコンテンツを使うようにしてください。

例えば:

$post_id = 125;
$post = get_post($post_id);

//Get the content, apply filters and execute shortcodes
$content = apply_filters( 'the_content', $post->post_content );
$embeds = get_media_embedded_in_content( $content );

//$embeds is an array and each item is the HTML of an embedded media.
//The first item of the array is the first embedded media in the content
$fist_embedded = $embeds[0];

上記のコードをあなたのものに似た関数に追加します。

function get_first_embed_media($post_id) {

    $post = get_post($post_id);
    $content = do_shortcode( apply_filters( 'the_content', $post->post_content ) );
    $embeds = get_media_embedded_in_content( $content );

    if( !empty($embeds) ) {
        //return first embed
        return $embeds[0];

    } else {
        //No embeds found
        return false;
    }

}

ビデオだけを制限するには、次のようにします。

function get_first_embed_media($post_id) {

    $post = get_post($post_id);
    $content = do_shortcode( apply_filters( 'the_content', $post->post_content ) );
    $embeds = get_media_embedded_in_content( $content );

    if( !empty($embeds) ) {
        //check what is the first embed containg video tag, youtube or vimeo
        foreach( $embeds as $embed ) {
            if( strpos( $embed, 'video' ) || strpos( $embed, 'youtube' ) || strpos( $embed, 'vimeo' ) ) {
                return $embed;
            }
        }

    } else {
        //No video embedded found
        return false;
    }

}

注: get_media_embedded_in_content()に、この回答が期待通りに機能しないというバグがありました bellow WP 4.2。

12
cybmeta