2. データベースへの保存
前回の記事で「特定のYouTuberの最新記事10件を取得する」ことができましたが、このままだとユーザーがページを開くたびにYouTubeDataAPIを使用することになります。
API使用料金を節約するため、一度WordPressのデータベースに動画情報を保存し、そこから情報を取り出す方法に変えます。
カラム名 | データ型 |
id | int AutoIncrement |
channel_name | text |
channel_id | text |
video_title | text |
video_url | text |
video_thumbnail | text |
video_published_at | datetime |
video_view_count | int |
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(); ?>