9ml

2. データベースへの保存

前回の記事で「特定のYouTuberの最新記事10件を取得する」ことができましたが、このままだとユーザーがページを開くたびにYouTubeDataAPIを使用することになります。

API使用料金を節約するため、一度WordPressのデータベースに動画情報を保存し、そこから情報を取り出す方法に変えます。

カラム名データ型
idint AutoIncrement
channel_nametext
channel_idtext
video_titletext
video_urltext
video_thumbnailtext
video_published_atdatetime
video_view_countint

YouTube Search API(チャンネル名からチャンネルIDを検索する)

YouTube Data API(動画タイトル、動画URL、サムネイル画像の取得)

YouTube Statistics API(動画投稿日、再生回数の取得)

<?php get_header(); ?>
<main>

<?php
function get_latest_youtube_video($channel_name, $api_key) {
	
    // チャンネル名からチャンネルIDを取得(YouTube Search API)
	// チャンネル名が日本語の場合はURLエンコードが必要
	$encoded_channel_name = urlencode($channel_name);
    $url = "https://www.googleapis.com/youtube/v3/search?key=$api_key&q=$encoded_channel_name&part=snippet&type=channel";
    $response = wp_remote_get($url);
    if (is_wp_error($response)) { exit; }
    $data = json_decode(wp_remote_retrieve_body($response));
    if ( isset($data->items[0]->snippet->channelId) ) {
        $channel_id = $data->items[0]->snippet->channelId;
    } else {
        return [];  // チャンネルIDが取得できなかった場合は空配列を返す
    }


    // 動画タイトルと動画URLとサムネイル画像をYouTube Data APIにリクエスト
    $url = "https://www.googleapis.com/youtube/v3/search?key=$api_key&channelId=$channel_id&order=date&part=snippet&type=video&maxResults=5";
    $response = wp_remote_get($url);
    if (is_wp_error($response)) { return []; }
    $data = json_decode(wp_remote_retrieve_body($response));

    if (isset($data->items)) {
        $videos = [];

        foreach ($data->items as $item) {
            // 動画公開日と再生回数を取得するためのURLを作成
            $video_id = $item->id->videoId;
            $stats_url = "https://www.googleapis.com/youtube/v3/videos?key=$api_key&id=$video_id&part=snippet,statistics";
            $stats_response = wp_remote_get($stats_url);
            if (is_wp_error($stats_response)) { continue; }
            $stats_data = json_decode(wp_remote_retrieve_body($stats_response));
            if (empty($stats_data->items)) { continue; }
            $statistics = $stats_data->items[0]->statistics;
            $snippet = $stats_data->items[0]->snippet;

            // 動画情報を保存
            $videos[] = [
                'title' => $item->snippet->title,
                'url' => 'https://www.youtube.com/watch?v=' . $item->id->videoId,
                'thumbnail' => $item->snippet->thumbnails->high->url,
                'published_at' => $snippet->publishedAt,
                'view_count' => isset($statistics->viewCount) ? $statistics->viewCount : 0
            ];
        }

        // データベースに保存
        global $wpdb;
        $table_name = $wpdb->prefix . 'youtube';

        foreach ($videos as $video) {
            // データをサニタイズして挿入
            $data = array(
				'channel_name' => sanitize_text_field($channel_name),
                'channel_id' => sanitize_text_field($channel_id),
                'video_title' => sanitize_text_field($video['title']),
                'video_url' => esc_url($video['url']),
                'video_thumbnail' => esc_url($video['thumbnail']),
                'video_published_at' => sanitize_text_field($video['published_at']),
                'video_view_count' => intval($video['view_count']),
            );
            $format = array('%s', '%s', '%s', '%s', '%s', '%d');
            $inserted = $wpdb->insert($table_name, $data, $format);
            if ($inserted === false) {
                echo 'データベースへの挿入に失敗しました: ' . $wpdb->last_error;
            } else {
                echo 'データベースに保存されました';
            }
        }

        return $videos;
    }

    return [];
}
?>

<?php
	// 最新記事の取得が2回目以降の場合は、一度該当チャンネルのレコードを削除してから、動画情報を取得する
	function delete_youtube_channel_data($channel_name) {
		global $wpdb;
		$table_name = $wpdb->prefix . 'youtube';
		$data = array(
			'channel_name' => $channel_name,
		);
		$format = array('%s');
		$wpdb->delete($table_name, $data, $format);
		if ( $wpdb->last_error ) { echo '削除エラー:' . $wpdb->last_error; }
	}
?>


<?php
if (isset($_POST['submit_channel_name'])) {

    $channelName = sanitize_text_field($_POST['input_channel_name']);
    $apiKey = 'あなたのAPIキー';

    if (empty($channelName)) {
        echo 'チャンネル名が入力されていません';
    } else {
		delete_youtube_channel_data($channelName);
        $videos = get_latest_youtube_video($channelName, $apiKey);
        if (empty($videos)) {
            echo '動画が見つかりませんでした。';
        } else {
            foreach ($videos as $video) {
                echo '<p>タイトル: ' . esc_html($video['title']) . '</p>';
                echo '<p>公開日: ' . esc_html($video['published_at']) . '</p>';
                echo '<p>再生回数: ' . esc_html($video['view_count']) . '</p>';
                echo '<p><a href="' . esc_url($video['url']) . '" target="_blank">動画を見る</a></p>';
            }
        }
    }
}
?>

<form method='post' action=''>
    <input type='text' name='input_channel_name' placeholder='チャンネル名'>
    <input type='submit' name='submit_channel_name' value='送信'>
</form>

</main>
<?php get_footer(); ?>
ホームに戻る