
WordPressのアイキャッチ設定って結構面倒くさいです。
そりゃ、一度ぐらいならさして面倒な事ではありません。けれど記事を書いて、投稿するたびに、毎回毎回設定していると面倒くさくなってきます。
しかもそのアイキャッチが、毎回投稿のトップにある画像に設定しているのなら、ついつい自動化したくなります。
そういう時のために、Auto Post Thumbnailというプラグインがあります。通常そういった場合は、このプラグインを使用すれば良いですが、今回は使っているテーマにこのAuto Post Thumbnailのような機能を付加する方法を紹介したいと思います。
ついでに、投稿内にYouTubeの動画があった場合は、動画のサムネイルを取得してアイキャッチにする機能も付けたいと思います。
カスタマイズ自体は、functions.phpにコードをコピペするのみになっているので、それほど難しくはないと思います。
目次
アイキャッチ自動設定カスタマイズ
アイキャッチ自動設定のカスタマイズ自体は、とても簡単です。
以下のコードを、親テーマでも子テーマでも良いので、functions.phpにコピペするだけです。
/////////////////////////////////////////////
//コピペ一発でWordpressの投稿時にアイキャッチを自動設定するカスタマイズ方法(YouTube対応版)
//https://nelog.jp/auto-post-thumbnail-custum
/////////////////////////////////////////////
//WP_Filesystemの利用
require_once(ABSPATH . '/wp-admin/includes/image.php');
//イメージファイルがサーバー内にない場合は取得する
function fetch_thumbnail_image($matches, $key, $post_content, $post_id){
//サーバーのphp.iniのallow_url_fopenがOnでないとき外部サーバーから取得しない
if ( !ini_get('allow_url_fopen') )
return null;
//正しいタイトルをイメージに割り当てる。IMGタグから抽出
$imageTitle = '';
preg_match_all('/<\s*img [^\>]*title\s*=\s*[\""\']?([^\""\'>]*)/i', $post_content, $matchesTitle);
if (count($matchesTitle) && isset($matchesTitle[1])) {
if ( isset($matchesTitle[1][$key]) )
$imageTitle = $matchesTitle[1][$key];
}
//処理のためのURL取得
$imageUrl = $matches[1][$key];
//ファイル名の取得
$filename = substr($imageUrl, (strrpos($imageUrl, '/'))+1);
if (!(($uploads = wp_upload_dir(current_time('mysql')) ) && false === $uploads['error'])){
return null;
}
//ユニーク(一意)ファイル名を生成
$filename = wp_unique_filename( $uploads['path'], $filename );
//ファイルをアップロードディレクトリに移動
$new_file = $uploads['path'] . "/$filename";
if (!ini_get('allow_url_fopen')) {
return null;
//$file_data = curl_get_file_contents($imageUrl);
} else {
if ( WP_Filesystem() ) {//WP_Filesystemの初期化
global $wp_filesystem;//$wp_filesystemオブジェクトの呼び出し
//$wp_filesystemオブジェクトのメソッドとしてファイルを取得する
$file_data = @$wp_filesystem->get_contents($imageUrl);
}
}
if (!$file_data) {
return null;
}
if ( WP_Filesystem() ) {//WP_Filesystemの初期化
global $wp_filesystem;//$wp_filesystemオブジェクトの呼び出し
//$wp_filesystemオブジェクトのメソッドとしてファイルに書き込む
$wp_filesystem->put_contents($new_file, $file_data);
}
//ファイルのパーミッションを正しく設定
$stat = stat( dirname( $new_file ));
$perms = $stat['mode'] & 0000666;
@ chmod( $new_file, $perms );
//ファイルタイプの取得。サムネイルにそれを利用
$mimes = null;
$wp_filetype = wp_check_filetype( $filename, $mimes );
extract( $wp_filetype );
//ファイルタイプがない場合、これ以上進めない
if ( ( !$type || !$ext ) && !current_user_can( 'unfiltered_upload' ) ) {
return null;
}
//URLを作成
$url = $uploads['url'] . "/$filename";
//添付(attachment)配列を構成
$attachment = array(
'post_mime_type' => $type,
'guid' => $url,
'post_parent' => null,
'post_title' => $imageTitle,
'post_content' => '',
);
$file = false;
$thumb_id = wp_insert_attachment($attachment, $file, $post_id);
if ( !is_wp_error($thumb_id) ) {
//attachmentのアップデート
wp_update_attachment_metadata( $thumb_id, wp_generate_attachment_metadata( $thumb_id, $new_file ) );
update_attached_file( $thumb_id, $new_file );
return $thumb_id;
}
return null;
}
//投稿内の最初の画像をアイキャッチに設定する(Auto Post Thumnailプラグイン的な機能)
function auto_post_thumbnail_image() {
global $wpdb;
global $post;
//$postが空の場合は終了
if ( isset($post) && isset($post->ID) ) {
$post_id = $post->ID;
//アイキャッチが既に設定されているかチェック
if (get_post_meta($post_id, '_thumbnail_id', true) || get_post_meta($post_id, 'skip_post_thumb', true)) {
return;
}
$post = $wpdb->get_results("SELECT * FROM {$wpdb->posts} WHERE id = $post_id");
//正規表現にマッチしたイメージのリストを格納する変数の初期化
$matches = array();
//投稿本文からすべての画像を取得
preg_match_all('/<\s*img [^\>]*src\s*=\s*[\""\']?([^\""\'>]*).+?\/?>/i', $post[0]->post_content, $matches);
//var_dump($matches);
//YouTubeのサムネイルを取得(画像がなかった場合)
if (empty($matches[0])) {
preg_match('%(?:youtube\.com/(?:user/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu\.be/)([^"&?/ ]{11})%i', $post[0]->post_content, $match);
if (!empty($match[1])) {
$matches=array(); $matches[0]=$matches[1]=array('http://img.youtube.com/vi/'.$match[1].'/mqdefault.jpg');
}
}
if (count($matches)) {
foreach ($matches[0] as $key => $image) {
$thumb_id = null;
//画像がイメージギャラリーにあったなら、サムネイルIDをCSSクラスに追加(イメージタグからIDを探す)
preg_match('/wp-image-([\d]*)/i', $image, $thumb_id);
if ( isset($thumb_id[1]) )
$thumb_id = $thumb_id[1];
//サムネイルが見つからなかったら、データベースから探す
if (!$thumb_id &&
//画像のパスにサイト名が含まれているとき
( strpos($image, site_url()) !== false ) ) {
//$image = substr($image, strpos($image, '"')+1);
preg_match('/src *= *"([^"]+)/i', $image, $m);
$image = $m[1];
if ( isset($m[1]) ) {
//wp_postsテーブルからguidがファイルパスのものを検索してIDを取得
$result = $wpdb->get_results("SELECT ID FROM {$wpdb->posts} WHERE guid = '".$image."'");
//IDをサムネイルをIDにセットする
if ( isset($result[0]) )
$thumb_id = $result[0]->ID;
}
//サムネイルなどで存在しないときはフルサイズのものをセットする
if ( !$thumb_id ) {
//ファイルパスの分割
$path_parts = pathinfo($image);
//サムネイルの追加文字列(-680x400など)を取得
preg_match('/-\d+x\d+$/i', $path_parts["filename"], $m);
//画像のアドレスにサイト名が入っていてサムネイル文字列が入っているとき
if ( isset($m[0]) ) {
//サムネイルの追加文字列(-680x400など)をファイル名から削除
$new_filename = str_replace($m[0], '', $path_parts["filename"]);
//新しいファイル名を利用してファイルパスを結語
$new_filepath = $path_parts["dirname"].'/'.$new_filename.'.'.$path_parts["extension"];
//wp_postsテーブルからguidがファイルパスのものを検索してIDを取得
$result = $wpdb->get_results("SELECT ID FROM {$wpdb->posts} WHERE guid = '".$new_filepath."'");
//IDをサムネイルをIDにセットする
if ( isset($result[0]) )
$thumb_id = $result[0]->ID;
}
}
}
//それでもサムネイルIDが見つからなかったら、画像をURLから取得する
if (!$thumb_id) {
$thumb_id = fetch_thumbnail_image($matches, $key, $post[0]->post_content, $post_id);
}
//サムネイルの取得に成功したらPost Metaをアップデート
if ($thumb_id) {
update_post_meta( $post_id, '_thumbnail_id', $thumb_id );
break;
}
}
}
}
}
//新しい投稿で自動設定する場合
add_action('save_post', 'auto_post_thumbnail_image');
add_action('draft_to_publish', 'auto_post_thumbnail_image');
add_action('new_to_publish', 'auto_post_thumbnail_image');
add_action('pending_to_publish', 'auto_post_thumbnail_image');
add_action('future_to_publish', 'auto_post_thumbnail_image');
add_action('xmlrpc_publish_post', 'auto_post_thumbnail_image');
ポイントとなるところには、コメントを入れてあるのですが、一応いくつか解説です。
ファイルの読み書き
以下のコードは、WP_Filesystemを利用するために記述します。
//WP_Filesystemの利用 require_once(ABSPATH . '/wp-admin/includes/image.php');
WordPressテーマなどから、file_get_contentsを直接呼ぶのは、作法的に良くない(というかセキュリティー的にだと思う)ので、WP_Filesystemのオブジェクトを介して取得する必要があります。
例としては、こんな感じで。
if ( WP_Filesystem() ) {//WP_Filesystemの初期化
global $wp_filesystem;//$wp_filesystemオブジェクトの呼び出し
//$wp_filesystemオブジェクトのメソッドとしてファイルを取得する
$file_data = @$wp_filesystem->get_contents($imageUrl);
}
詳しくは以下を参照してください。
それぞれの関数の動作
fetch_thumbnail_image()は、画像がデータベースにない場合は、WEB上の画像URLからファイルを取得する関数です。今回は、YouTubeのサムネイルを取得するのに利用しています。
auto_post_thumbnail_image()は、投稿にアイキャッチが設定されていなかったら、投稿本文の最初に出てくる画像をアイキャッチに設定します。
投稿本文に画像がなくてYouTubeの埋め込みがあったら、YouTubeのサムネイルをアイキャッチに設定します。
画像と、YouTubeの埋め込みが両方あった場合は、画像の方が優先されます。
上記のコードを作成するのに、以下の情報をまぜ合わせて利用させてもらいました。
- Auto Post Thumbnailのソース
- Set Default Thumbnail, Featured Image and Fallback Image in WordPress Automatically
- Dream Seed » YouTubeの動画からブログ記事のアイキャッチ画像を自動的に作成する方法
あと、YouTubeのサムネイルに関しては以下が参考になります。
- [YouTube]YouTubeのサムネイル画像(default.jpg mqdefault.jpg hqdefault.jpg sddefault.jpg maxresdefault.jpg): [FORCE]
- Youtube の動画で様々なサイズのサムネイル画像を取得する方法
- トピック: Auto Post Thumbnailを入れましたが・・・。のhidekichiさんの書き込み
動作確認
で、肝心の動作です。
画像の自動アイキャッチ設定
新しい投稿作成して、以下のように設定して公開すると

一番最初に出てくる画像が「アイキャッチ画像」に設定されています。

YouTube動画の自動アイキャッチ設定
例えば、WordpressのoEmbed(埋め込み)機能で、投稿本文に以下のように書いて公開ボタン押すと
https://www.youtube.com/watch?v=cvj3-MZO9Tw

YouTubeから、最初に登場する動画のmqdefault.jpg(320×180px)サイズのサムネイルが、自動で取得され「アイキャッチ画像」に自動設定されます。

もちろん、WordpressのoEmbedではなく、YouTubeの以下のようなiframe埋め込みを利用してもサムネイルは取得されます。
<iframe width="560" height="315" src="https://www.youtube.com/embed/cvj3-MZO9Tw" frameborder="0" allowfullscreen></iframe>
注意点
今回の方法では、画像とYouTube埋め込みを同時に本文中に挿入した場合は、最初に登場する画像が優先的にアイキャッチに設定されます。
YouTubeの埋め込みが先頭に記入されていても、本文中に画像が使用されていれば、画像が「アイキャッチ画像」に設定されます。
ここらへんを、修正するには、画像とYouTubeを判別する正規表現部分を、適切なものに変更してください。
まとめ
とりあえず、コードに書かれている内容を特に気にしなければ、カスタマイズ自体は1回のコピペだけで行える簡単なものです。編集に1分もかかりません。
ただ、画像だけをアイキャッチに自動設定したければ、Auto Post Thumbnailプラグインを利用した方が無難かと思います。
また、YouTubeのサムネイルをアイキャッチに自動設定したい場合は、有料ですがAuto Post Thumbnail PROというのもあるようです。この記事を書いた時点では、8ドルで購入できます。
「いつも使用しているテーマに自動アイキャッチ設定機能をつけて、プラグインのインストールを不要にしたい」とか、「YouTube動画を紹介するページで、毎回アイキャッチ設定が面倒くさい」なんて方には、有効なカスタマイズ方法かもしれません。
お前の推奨したクソテンプレートのせいで、ワードプレスがぐちゃぐちゃになったじゃねーかお前のサイトを鵜呑みにするんじゃなかったは。