<?php
// 参考サイト
// https://dis-play.net/wordpress/tips/blogcard-external/
// キャッシュテーブル作成
function add_yagi_out_blog_card_cache_table() {
global $wpdb;
global $table_that_yagi_out_blog_card;
$charset_collate = $wpdb->get_charset_collate();
// https://www.dbonline.jp/mysql/type/
$sql = "CREATE TABLE $table_that_yagi_out_blog_card (
id mediumint(9) NOT NULL AUTO_INCREMENT,
url varchar(1000) DEFAULT '' NOT NULL,
time datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
title text DEFAULT NULL,
content text DEFAULT NULL,
pict MEDIUMBLOB DEFAULT NULL,
favicon MEDIUMBLOB DEFAULT NULL,
UNIQUE KEY id (id)
) $charset_collate;";
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
dbDelta( $sql );
}
// キャッシュテーブル削除
function dll_yagi_out_blog_card_cache_table() {
global $wpdb;
global $table_that_yagi_out_blog_card;
$sql = "DROP TABLE " . $table_that_yagi_out_blog_card;
$wpdb->query($sql);
}
/**
* 画像のリサイズ+トリミング
*
* @return string $fileUrl urlもしくは画像ファイル
*/
function yagi_resize_img($fileUrl) {
//トリミングサイズ
$thumbW = 130;
$thumbH = 130;
//元の画像のサイズを取得する
// list($w, $h) = getimagesize($fileUrl);
$imginfo = getimagesize($fileUrl);
$w = $imginfo[0];
$h = $imginfo[1];
$img_type = $imginfo['mime'];
//元画像の縦横の大きさを比べてどちらかにあわせる
// なおかつ縦横の差をコピー開始位置として使えるようセット
if($w > $h){
$diff = ($w - $h) * 0.5;
$diffW = $h;
$diffH = $h;
$diffY = 0;
$diffX = $diff;
}elseif($w < $h){
$diff = ($h - $w) * 0.5;
$diffW = $w;
$diffH = $w;
$diffY = $diff;
$diffX = 0;
}elseif($w === $h){
$diffW = $w;
$diffH = $h;
$diffY = 0;
$diffX = 0;
}
//サムネイルになる土台の画像を作る
$thumbnail = imagecreatetruecolor($thumbW, $thumbH);
//元の画像を読み込む
if ($img_type === 'image/jpeg') {
$baseImage = imagecreatefromjpeg($fileUrl);
} elseif ($img_type === 'image/png') {
$baseImage = imagecreatefrompng($fileUrl);
} else {
// 該当しないNULLなどの場合は適当なベース画像を作る
$baseImage = imagecreatetruecolor($thumbW, $thumbH);
}
//サムネイルになる土台の画像に合わせて元の画像を縮小しコピーペーストする
imagecopyresampled($thumbnail, $baseImage, 0, 0, $diffX, $diffY, $thumbW, $thumbH, $diffW, $diffH);
ob_start(); // start a new output buffer
imagejpeg( $thumbnail );
$ImageData = ob_get_contents();
ob_end_clean(); // stop this output buffer
return $ImageData;
}
// キャッシュスプリント
// yagi_out_blog_card_cache
// https://qiita.com/okdyy75/items/669dd51b432ee2c1dfbc#db%E3%81%AB%E4%BF%9D%E5%AD%98%E3%81%97%E3%81%A6%E8%A1%A8%E7%A4%BA
function yagi_out_blog_card_cache($url, $title, $content, $pict, $favi) {
global $wpdb;
global $table_that_yagi_out_blog_card;
// wp api はエラーが出るためこれで対応
$pict = yagi_out_blog_card_file_get_contents($pict);
$favi = file_get_contents($favi);
$wpdb->insert(
$table_that_yagi_out_blog_card,
array(
'time' => current_time( 'mysql' ),
'url' => $url,
'title' => $title,
'content' => $content,
'pict' => $pict,
'favicon' => $favi,
)
);
}
// ワードプレスAPIから取得を行う場合
function yagi_out_blog_card_file_get_contents($pict_url) {
// https://teratail.com/questions/31417
$ctx = stream_context_create(array(
'http' => array(
'method' => 'GET',
'header' => 'User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; Touch; rv:11.0) like Gecko')
)
);
// wp api はエラーが出るためこれで対応
$pic_file = file_get_contents($pict_url, false, $ctx);
// 通常ファイルを一旦data化する
$pic_file = change_yagi_out_blog_card_db_pic($pic_file);
// data化した後にリサイズし、リターン
return yagi_resize_img($pic_file[0]);
}
function get_yagi_out_blog_card_cache($url) {
global $wpdb;
global $table_that_yagi_out_blog_card;
$query = $wpdb->prepare("
SELECT *
FROM $table_that_yagi_out_blog_card
WHERE url = %s
LIMIT 1
", strval($url));
$results = $wpdb->get_results($query);
if (empty($results)) {
return false;
}
$results = $results[0];
// var_dump($results);
// echo $results->pict;
$results->pict = change_yagi_out_blog_card_db_pic($results->pict);
$results->favicon = change_yagi_out_blog_card_db_pic($results->favicon);
// var_dump($results->pict);
// echo $results->pict;
// echo $results->favicon;
return $results;
}
// ※DBを変更するスクリプトではない。写真形式base64をつくるスクリプト
function change_yagi_out_blog_card_db_pic($pic) {
$enc_img = base64_encode($pic);
$imginfo = getimagesize('data:application/octet-stream;base64,' . $enc_img);
// データの型を配列で返す
return ['data:' . $imginfo['mime'] . ';base64,' . $enc_img, $imginfo['mime']];
}
/**
* 内部リンクのカードリンクの HTML を作成
*
* @param int $id 投稿 ID
* @param array $atts ユーザーがショートコードタグに指定した属性
* @return string カードリンクの HTML
*/
function yagi_get_internal_blog_card( $id, $atts ) {
// ID から投稿情報を取得
$post = get_post( $id );
// 投稿日を取得
$date = mysql2date( 'Y.m.d', $post->post_date );
// タイトルを取得
$title = $atts['title'] ? $atts['title'] : get_the_title( $id );
$title = is_mobile() ? wp_trim_words( $title, 42, '...' ) : $title;
// 抜粋を取得
$excerpt = $atts['excerpt'];
if ( ! $excerpt ) {
if ( $post->post_excerpt ) {
$excerpt = get_the_custom_excerpt( $post->post_excerpt, 70 );
} else {
$excerpt = get_the_custom_excerpt( $post->post_content, 70 );
}
}
$excerpt = is_mobile() ? wp_trim_words( $excerpt, 50, '...' ) : $excerpt;
// アイキャッチ画像を取得
if ( has_post_thumbnail( $id ) ) {
$img = wp_get_attachment_image_src( get_post_thumbnail_id( $id ), 'size-card' );
$img = $img[0];
} else {
$img = get_template_directory_uri() . '/img/common/no_image1.gif';
}
// 内部リンク用ブログカードHTML出力(返却)
$clink = '<div class="cardlink">
<a href="' . esc_url( $atts['url'] ) . '">
<div class="cardlink_thumbnail">
<img src="' . esc_attr( $img ) . '">
</div>
</a>
<div class="cardlink_content">
<span class="cardlink_timestamp">' . esc_html( $date ) . '</span>
<div class="cardlink_title">
<a href="' . esc_url( $atts['url'] ) . '">' . esc_html( $title ) . '</a>
</div>
<div class="cardlink_excerpt"><span>' . esc_html( $excerpt ) . '</span></div>
</div>
<div class="cardlink_footer"></div>
</div>' . "\n";
return $clink;
}
/* 外部リンク対応ブログカードのショートコードを作成 */
function show_Linkcard($atts) {
global $wpdb;
global $table_that_yagi_out_blog_card;
extract(shortcode_atts(array(
'id'=>"",
'url'=>"",
'title'=>"",
'excerpt'=>""
),$atts));
// ID、URLの両方とも指定がない場合はリターン
if ( empty($id) && empty($url) ) { return; }
// 内部リンクの場合はリターン
// $idが空、[0]["0"]でない場合
if (!empty($id)) {
// 記事IDからURLを作成し連想配列に代入=>ID,URLを合わせる
$atts['url'] = get_permalink( $id );
return yagi_get_internal_blog_card( $id, $atts );
}
// URL から投稿 ID を取得
$id = url_to_postid( $url );
if (!empty($id)) {
return yagi_get_internal_blog_card( $id, $atts );
}
// ======== ↓↓↓外部リンク作成↓↓↓ ========
//画像サイズの横幅を指定
$img_width ="130";
//画像サイズの高さを指定
$img_height = "130";
$blog_card_info = get_yagi_out_blog_card_cache($url);
if ($blog_card_info) {
$url = $blog_card_info->url;
$Link_title = $blog_card_info->title;
$Link_description = $blog_card_info->content;
$xLink_img = $blog_card_info->pict[0];
$favicon = $blog_card_info->favicon[0];
} else {
// プラグインの衝突を防ぐ
// OpenGraphクラスが定義されていない場合にのみ1回だけ読み込む
if (!class_exists('OpenGraph')) { require_once 'OpenGraph.php'; }
// OGP情報を取得
$graph = OpenGraph::fetch($url);
// OGPタグからタイトルを取得
$Link_title = $graph->title;
if(!empty($title)){
$Link_title = $title;// title=""の入力がある場合はそちらを優先
}
// OGPタグからdescriptionを取得(抜粋文として利用)
$Link_description = wp_trim_words($graph->description, 160, '…' );//文字数は任意で変更
if(!empty($excerpt)){
$Link_description = $excerpt;//値を取得できない時は手動でexcerpt=""を入力
}
// 三項演算子
// $graph->imageがある場合はアイキャッチ画像を表示
// wordpress.comのAPIを利用してスクリーンショットを取得
$screenShot = $graph->image ? $graph->image : 'https://s.wordpress.com/mshots/v1/'. urlencode(esc_url(rtrim( $url, '/' ))) .'?w='. $img_width .'&h='.$img_height.'';
//スクリーンショットを表示
$xLink_img = $screenShot;
// var_dump($screenShot);
//ファビコンを取得(GoogleのAPIでスクレイピング)
$host = parse_url($url)['host'];
$searchFavcon = 'https://www.google.com/s2/favicons?domain='.$host;
if($searchFavcon){
$favicon = $searchFavcon;
} else { // ファビコンが無い場合
$favicon = "";
}
// echo $screenShot;
// echo $searchFavcon;
yagi_out_blog_card_cache($url, $Link_title, $Link_description, $screenShot, $searchFavcon);
}
// ワードプレスapiからのデータがデフォルト(image/gif)の場合データベースを更新
if ($blog_card_info && $blog_card_info->pict[1] == 'image/gif') {
// echo $blog_card_info->pict[1].'<br />';
// var_dump($blog_card_info);
//wordpress.comのAPIを利用してスクリーンショットを取得
$screenShot = 'https://s.wordpress.com/mshots/v1/'. urlencode(esc_url(rtrim( $url, '/' ))) .'?w='. $img_width .'&h='.$img_height.'';
$add_img = yagi_out_blog_card_file_get_contents($screenShot);
$wpdb->update(
$table_that_yagi_out_blog_card,
array(
'pict' => $add_img
),
array( 'ID' => $blog_card_info->id )
);
// $xLink_imgもついでに反映させたい
$xLink_img = change_yagi_out_blog_card_db_pic($add_img)[0];
}
// 外部リンク用ブログカードHTML出力
$sc_Linkcard ='<div class="cardlink">
<a href="' . esc_url( $url ) . '">
<div class="cardlink_thumbnail">
<img src="' . esc_attr( $xLink_img ) . '">
</div>
</a>
<div class="cardlink_content">
<div class="cardlink_title">
<a href="' . esc_url( $url ) . '">' . esc_html( $Link_title ) . '</a>
</div>
<div class="cardlink_excerpt"><span>' . esc_html( $Link_description ) . '</span></div>
</div>
<div class="cardlink_footer"><img src="' .esc_attr( $favicon ). '"> ' . $url .'</div>
</div>' . "\n";
return $sc_Linkcard;
}
// ショートコードに追加
add_shortcode("bc", "show_Linkcard");
コメント