• 追加された行はこの色です。
  • 削除された行はこの色です。
#author("2021-03-28T08:07:12+09:00;2020-02-15T03:11:54+09:00","default:kanateko0404","kanateko0404")
#author("2021-03-28T14:07:13+09:00","default:kanateko0404","kanateko0404")
RIGHT:&tag(カスタマイズ,プラグイン改造);

#contentsx

*変更箇所のまとめ [#b2cbdde4]
-XSS対策
-ページ名からリンクを作成する機能を追加。 (内部リンクのみ)
-ベースネーム表示機能の追加。
-画像非表示機能の追加。
-ページ名からリンクを作成する機能を追加。 (内部リンクのみ)
-画像の拡張子を判別して表示する機能追加。
-画像のキャッシュ方法を変更。
-その他細かい変更。

*変更の詳細 [#sf783ded]
**XSS対策を施す [#xss]
そのまま使うとXSSの危険性があったためいくつか修正を施す。
**ページ名からリンクを作成する [#h598e79a]
内部リンクの場合、いちいち自身のサイトのURLを貼るのも面倒なので、ページ名指定ができるようにする。また、このサイトではURL短縮ライブラリを導入しているため、合わせてそれにも対応する。

***URLが不正であった場合にエラーを返すようにする [#df9631c3]
デフォルトだとURL先のページが存在しなかった場合でもカードの作成に入ってしまうので、そこを修正する。

#prism(diff-php diff-highlight){{
    $graph = OpenGraph::fetch($ogpurl[0]);
    if ($graph) {
      ...
-   }
+   } else return '#ogp Error: Page not found.';
 	$args = func_get_args();
-	$uri = get_script_uri();
-	$ogpurl = (explode('://', $args[0]));
+	$uri = array_shift($args);
+    if (strpos($uri, '://') === false) {
+        $uri = get_base_uri(PKWK_URI_ABSOLUTE) . get_short_url_from_pagename($uri);
+    }
+	$ogpurl = (explode('://', $uri));
}}

***カード作成前にサニタイズする [#c290a14b]
例えばリンク先がWikiだった場合、存在しないページでも編集画面に繋がってしまう。
そのため上記修正のみだと不十分なため、return前の適当な場所で引数をサニタイズしておく。
ついでに元のプラグインだと$uri (と$url) が使われていなかったため、第一引数に置き換えて$args[0]になっている箇所全てと入れ替えた。

#prism(diff-php diff-highlight){{
  $imgtag = 'img class="ogp-img"' ;
}
**ベースネーム表示機能を追加 [#h7cc6ff8]

+ $ogpurl[0] = htmlsc($ogpurl[0]);

  return <<<EOD
}}

修正箇所を2つ挙げたものの、XSS対策としては2つ目 (サニタイズ) のみでも大丈夫。多分。

**ベースネーム表示と画像非表示オプションを追加 [#h7cc6ff8]

:ベースネーム表示機能|
Wikiだとページ名が "AAA/BBB/CCC" のように階層化されている場合がある。
この "CCC" に当たる部分がベースネーム。
階層が深くなりすぎると、ページ名が長すぎて行数制限内に収まりきらないことがあるため、オプションでベースネームのみを表示するように指定できるようにする。

:画像非表示機能|
デフォルトだとリンク先のOGPタグに画像が指定されていないと表示が崩れるため、画像そのものを非表示にする機能を追加する。

最後の方にあるampオプションの処理部分を改変する。
#prism(diff-php diff-highlight){{
-if($ogpurl[1] == "amp"){
-    $imgtag = 'amp-img class="ogp-img" layout="fill"' ;
-} else {
-    $imgtag = 'img class="ogp-img"' ;
-}
+foreach ($ogpurl as $param) {
+	switch ($param) {
+		case 'amp': // amp
+			$imgtag = 'amp-img class="ogp-img" layout="fill"' ;
+			break;
+		case 'noimg': // 画像なし
+			$imgtag = 'img class="ogp-noimg"';
+			break;
+		case 'base': // ページのbasenameのみを表示 (Wiki系のサイト用)
+			$title = array_pop(explode('/',$title));
+		default:
+			break;
	$is_amp = (in_array('amp', $args) || PLUGIN_OGP_AMP );
	$is_noimg = (in_array('noimg', $args) || filesize($imgcache) == 0 );
 	$is_prefetch = in_array('prefetch', $args);
+	$is_base = in_array('base', $args);
}}
#prism(diff-php diff-highlight){{
 	} else {
 		$prefetch = '';
 	}
 
+	if($is_base) {
+		$title = array_pop(explode('/', $title));
+	}
+}
+if (!isset($imgtag)) $imgtag = 'img class="ogp-img"';
}}

CSSに以下を追加。
#prism(css){{
img.ogp-noimg { display: none; }
}}
**画像のキャッシュ方法を変更 [#n56d941e]
元のプラグインだと拡張子ごとに変数を用意して一つ一つチェックしていたが、個人的にもうちょっとスマートにしたかったので処理を変えていく。

まず$webp以外の拡張子用の変数を省略する。

**画像の拡張子を判別する [#s3af354b]
そのままだと画像を全て.imgで保存・表示していたため、拡張子を判別する機能を追加する。
#prism(diff-php diff-highlight){{
 	$ogpurlmd = md5($ogpurl[1]);
 	$datcache = CACHE_DIR . 'ogp/' . $ogpurlmd . '.dat';
-	$gifcache = CACHE_DIR . 'ogp/' . $ogpurlmd . '.gif';
-	$jpgcache = CACHE_DIR . 'ogp/' . $ogpurlmd . '.jpg';
-	$pngcache = CACHE_DIR . 'ogp/' . $ogpurlmd . '.png';
	if(PLUGIN_OGP_WEBP_FALLBACK) {
	$webpcache = CACHE_DIR . 'ogp/' . $ogpurlmd . '.webp'; //webp対応
	}
}}

まず$imgcacheを別の場所で使うため省略。
キャッシュの有無の判別、およびキャッシュがある場合の処理を変える。

#prism(diff-php diff-highlight){{
 $datcache = CACHE_DIR . 'ogp/' . $ogpurlmd . '.dat';
-$imgcache = CACHE_DIR . 'ogp/' . $ogpurlmd . '.img';
-	if(file_exists($pngcache)) { $imgcache = $pngcache ; }
-	else if(file_exists($gifcache)) { $imgcache = $gifcache ; }
-	else { $imgcache = $jpgcache ; }
-	
-	if(file_exists($datcache) && file_exists($imgcache)) {
+	if(file_exists($datcache)) {
 		$ogpcache = file_get_contents($datcache);
 		$ogpcachearray = explode("<>", $ogpcache);
 		$title = $ogpcachearray[0];
 		$description = $ogpcachearray[1];
-		$src = $imgcache ;
-		$imgfile = file_get_contents($imgcache) ;
+		$src = $ogpcachearray[2];
 	} else {
 	    require_once(PLUGIN_DIR.'opengraph.php');
-	    $graph = OpenGraph::fetch($args[0]);    
+	    $graph = OpenGraph::fetch($uri);    
 	    if ($graph) {
 	        $title = $graph->title;
-	        $url = $graph->url;
 	        $description = $graph->description;
 	        $src = $graph->image;
}}

キャッシュがある場合の処理を改変。
datから画像パスを持ってくる。
キャッシュがない場合の処理を変える。

#prism(diff-php diff-highlight){{
-if(file_exists($datcache) && file_exists($imgcache)) {
+if (file_exists($datcache)) {
 	$ogpcache = file_get_contents($datcache);
 	$ogpcachearray = explode("<>", $ogpcache);
 	$title = $ogpcachearray[0];
 	$description = $ogpcachearray[1];
-	$src = $imgcache ;
+	$src = $ogpcachearray[2];
 } else {
 		        $description = mb_convert_encoding($description, 'UTF-8', mb_detect_encoding($description, $detects, true));
 		    }
 		    
+			// 画像キャッシュ生成
 			$imgfile = file_get_contents($src);
-			$imginfo = getimagesize($src);
-			file_put_contents($datcache, $title . '<>' . $description . '<>' . $args[0]);
-			$filetype = $imginfo[2];
-			if( $filetype == 1 ){
-				file_put_contents($gifcache, $imgfile) ;
-			} else if ( $filetype == 3 ){
-				file_put_contents($pngcache, $imgfile) ;
-			} else {
-				file_put_contents($jpgcache, $imgfile) ;
-			} //どの拡張子でもない場合どうするか(webp,gzip)、jpg拡張子に偽装したgzファイルなどでエラーが出る
+			$fileinfo = pathinfo($src);
+			$imgcache = CACHE_DIR . 'ogp/' . $ogpurlmd . '.' . $fileinfo['extension'];
+			file_put_contents ($imgcache, $imgfile);
+
+			// OGPキャッシュ生成
+			file_put_contents($datcache, $title . '<>' . $description . '<>' . $imgcache . '<>' . $uri);
 		} else return '#ogp Error: Page not found.';
 	}
}}

キャッシュがない場合の処理を改変。
拡張子の判別と画像の保存、datへの書き込みを行う。
一応元に倣って$uri ($args[0]) も保存しているが、今のところどこにも使ってないので消してもいいかもしれない。

**その他細かい変更点 [#a3295dcb]
***PukiWiki1.5.3の使用に合わせる [#w84f6676]
htmlspesialchars -> htmlsc
#prism(diff-php diff-highlight){{
        $imgfile = file_get_contents($src);
-       $imginfo = pathinfo($src);
-       /* $imgname = $imginfo['basename']; */
-       file_put_contents($datcache, $title . '<>' . $description . '<>' . $ogpurl[0]);
-       file_put_contents($imgcache, $imgfile);
+       if (empty($imgfile)) {
+           // file_get_contentsに失敗したら専用画像表示
+           // $imgcache = $src; ← 直リンver (オススメはしない)
+           $imgcache = IMAGE_DIR . 'noimg.jpg';
+       } else {
+           // 成功したら画像を保存
+           $extension = array_pop(explode('.', $src)); // 拡張子を取得
+           if (preg_match('/(.+)(\?|\&).+/', $extension, $match)) {
+               $extension = $match[1];
+           }
+           $imgcache = CACHE_DIR . 'ogp/' . $ogpurlmd . '.' . $extension;
+           file_put_contents($imgcache, $imgfile);
+           }
+           file_put_contents($datcache, $title . '<>' . $description . '<>' . $imgcache);
-	$args[0] = htmlspecialchars($args[0]);
+	$uri = htmlsc($uri);
}}

***noimg判定の修正 [#o22552c8]
filesizeがローカルでしか使えないようなので、判定方法を下記のように変更する。
#prism(diff-php diff-highlight){{
-	$is_noimg = (in_array('noimg', $args) || filesize($imgcache) == 0 );
+	$is_noimg = (in_array('noimg', $args) || filesize($imgcache) === 0 || empty($src) );
}}

もしくは画像キャッシュ生成した後に$srcに$imgcacheを代入する。


----


*更新履歴 [#zd9d78cb]
:2021/03/28|
プラグイン本体の方が更新されていたので、それに対応し記述を修正。
XSS対策やnoimgオプションを取り込んでいただけたようで、嬉しい反面自身もコーディングに自信があるわけではないのでちょっとドキドキする。

*プラグイン配布元 [#o7247373]
[[pukiwikiカスタマイズ箇所/ogp.inc.php - 腫瘍学レ点ノート:https://oncologynote.com/?c7fc224f04]]

*コメント [#od0c917c]
質問や指摘などあればどうぞ。
----
#pcomment2(,10,above,reply)

#pcomment(,10,above,reply)