まあ事後報告なんですけれども。
この前の話の続きなんですが、熟考に熟考を重ねた結果、
日記の記事ページの方を書き換えて実装するという方針に出ました。
メモ代わりに、実装の方針の説明をしますね。
<?php
$div_id=1;
if(isset($u_h)){$include_check=1;}else{ $include_check=0;
require "../../../php/Diary_R/function.php";
list($d_y,$d_m,$d_d,$u_h)=get_ymdu();
require "./0_index.php"; ?>
<!DOCTYPE HTML><HTML class="diary"><HEAD><?php include "../../../header_set.php";?><TITLE>「<?php echo $index[$d_d+0][0];?>」(<?php echo $d_y;?>/<?php echo $d_m+0;?>/<?php echo $d_d+0;?>) - 見てはいけない黒歴史</TITLE></HEAD><BODY class="diary"><?php diary_main($d_y,$d_m,$d_d);}?><!--__diary_start__-->
<div class="contents">
<?php day_r($d_y,$d_m,$d_d,$index[$d_d+0]);$count=0;$number=0;$d_title=$index[$d_d+0][$number];$ymd=array($d_y,$d_m,$d_d,$u_h);?>
<?php diary_l($ymd,"-2");?>この前の話</a>の続きなんですが、熟考に熟考を重ねた結果、<span class="color_strong"><b>日記の記事ページの方を書き換えて実装する</b></span>という方針に出ました。<br>
<br>
<br>
メモ代わりに、実装の方針の説明をしますね。
</pre>
</div>
<br>
<?php diary_footer_addcomment_r($d_y,$d_m,$d_d,$d_title);if($include_check==0){diary_end($d_y,$d_m,$d_d);?><!--__diary_end__-->
</BODY></HTML><?php }?>
いま、記事ごとのページはこんな実装になってます。
ひと目でわかるやばいコードですね。
一番最初の
$div_id=1とか
製作者の僕が見ても意味がわかりません(やばい)
トップページに日記を埋め込んでる関係上、トップページと共通のコードを使ってる
はずなので、トップページから呼ばれてるのか、日記の記事ページから呼んでるのかを判別するためのフラグだった
はずなのですが、まず命名を$is_divとかにすべきですし、
なんでbooleanじゃないねんって感じですし、もっといえば
定数でええやん・・・・・・って気がします。
まずやりたいことの大枠として、twitterからのアクセスか否かでの表示切り替えですね。
リファラはphpで取れるので、twitter.comからのアクセスであれば特殊処理に入る、って感じで良さそうですね。
twitter以外からのアクセスであればすべての処理を飛ばして従来どおりの表示にすれば良い、と。
で、その特殊処理の内容としては・・・・・・
(1)トップページに表示されている範囲かどうかの判定
(2)トップページに表示されている範囲内へのアクセスであれば、トップページを「表示」する
という流れになります。
トップページはincludeで雑に埋め込めばいいかなって感じはするんですが、一応ソースを見ておきましょう。
<?php
include "./index_phps.php";
?>
<!DOCTYPE HTML>
<Html lang="ja">
<Head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="canonical" href="http://trc-vlackhistory.net/" />
<?php
include "./header_set.php";
?>
<link href="./style.css" rel="stylesheet" type="text/css">
<style>
<!--@import url(https://fonts.googleapis.com/css?family=Raleway:200);@charset "UTF-8";-->
</style>
<link href="./fit-sidebar.css" rel="stylesheet" type="text/css" media="screen" >
<link href="./php/D_comment/style.css" rel="stylesheet" type="text/css">
<script src="./fit-sidebar.js"></script>
<Title>見てはいけない黒歴史 in -The Rong's Caravan-</Title>
</Head>
<Body>
......
こんな感じになってます。
<?php
include "./index_phps.php";
?>
<!DOCTYPE HTML>
<Html lang="ja">
<Head>
***この部分にSNS用のMETAタグが入るはず***
***よって↓この行以下↓を関数に切り分けて呼べるように出来たら勝ち***
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="canonical" href="http://trc-vlackhistory.net/" />
<?php
include "./header_set.php";
?>
<link href="./style.css" rel="stylesheet" type="text/css">
<style>
<!--@import url(https://fonts.googleapis.com/css?family=Raleway:200);@charset "UTF-8";-->
</style>
<link href="./fit-sidebar.css" rel="stylesheet" type="text/css" media="screen" >
<link href="./php/D_comment/style.css" rel="stylesheet" type="text/css">
<script src="./fit-sidebar.js"></script>
<Title>見てはいけない黒歴史 in -The Rong's Caravan-</Title>
</Head>
<Body>
という図式になりますね。
とりあえず、雑に関数でくくって出してみましょう。
・・・・・・ですよね。(だっる・・・・・・)
関数に切り分けるのが不可能そうなので、方針としては2つあります。
一つは、index.phpをそのままincludeしますが、フラグ管理により最初の数行を読み飛ばすことでhtmlとしての整合性を保つ方法。
もうひとつは
ページ全体をiframeでindex.phpを埋め込んでしまえという
過激派の発想です(笑)
どちらの方法にも問題を孕んでいまして、例えば前者だと読み出し元が変わることにより相対パスが変わることでそのあたりがバグります。
これは僕のスパゲティコードが原因です。
後者は一見単純そうに見えますが、https同士でないとリファラが取れないらしく日記ページはアクセスURLを変えるだけでhttps化できるので問題ないのですが、トップページはhttps対応するために各リンクを張り替える必要があります。こう一言で言うと簡単なのですが、httpsにするにはhttpへのリンクがあってはいけないので、言い換えると
トップページに関連するすべてのページをhttps対応する必要があります。僕がこの作業をめんどくさがっていつまでも放置しているのが原因です。
とりあえず前者の実装の方が優等生チックで失敗が少なそうなのでとりあえずそれでなんとかやってみます。
事後報告ってぐらいなので実装は終わったんですが、振り返ってみれば
スパゲッティーコードに拍車をかけることになったって感じですね。気になる人はいないと思いますが、さらっと見せてあげます(何)
...
require "./0_index.php";if(is_from_twitter($_SERVER)&&is_displaying_on_index($d_y,$d_m,$d_d)){$display_index_mode=true;} ?>
<!DOCTYPE HTML><HTML class="diary"><HEAD><?php rawText($d_y,$d_m,$d_d,$index);if(isset($display_index_mode)){include("../../../index.php");exit();}include "../../../header_set.php";?><TITLE>
...
日記本体のページはこのような記述に変わりました。いくつか追加されてますね。
is_from_twitter()という関数でtwitterからの流入をチェックするつもりだったのですが、途中で方針が変わり
自サイト以外の流入かどうかチェックするという関数に実体がいつのまにかすげかわってます()
名前と動作が一致しない関数とかゴミすぎるんですが、変えるのめんどくさかったのでそのままにしました。
外部流入ではない、もしくはリンク直打ちならそのまま終了するのですが、その後の
is_displaying_on_indexという関数では、
トップページに表示されている範囲かどうかをチェックします。トップページに表示されている範囲外でのアクセスであれば、トップページを表示する理由もないので従来どおりのページになるように処理を分岐させます。
で、もし外部流入かつトップページ範囲内であれば、トップページを表示させたいので、
$display_index_modeというのをONにします。こういうのは定数が良かったんですが、この場所じゃ定数が定義できなかったので変数で妥協しました(笑)
で、headタグ内の
rawText()ってのがtwitterカードに必要なタグを生成している場所で、これがあることで2019年1月以降の日記にリンクを貼ると、twitterカードが表示されるようになります。
で、最後にフラグが立っている場合、トップページをそのままインクルードし処理を強制終了させます。関数に切り分けることが不可能だったのでこういう形になりました。ぐっちゃぐちゃですね。でも個人的にはこれでよくまとまったなぁと関心してます()
まぁプログラミングを知ってる方からすればわかると思うんですが、めっちゃヒドい実装です(笑)つぎはぎもいいとこである・・・・・・。こうやってメンテナンス不能コードが出来上がっていくんだなあ、、、笑
//2019/1/1以降
function is_from_twitter($server):bool{
if(!isset($server['HTTP_REFERER'])){return false;}
if(strpos($server['HTTP_REFERER'],'localhost') !== false){return false;}
return (strpos($server['HTTP_REFERER'],'trc-vlackhistory') === false);
}
function is_displaying_on_index($d_y,$d_m,$d_d):bool{//その日程がトップページに表示されているのか
$from_display=true;//index_phps.php用のフラグ
include ("../../../index_phps.php");
return (new Datetime($d_y."/".$d_m."/".$d_d))>=(new Datetime($diary[2][0]."/".$diary[2][1]."/".$diary[2][2]));
}
function rawText($d_y,$d_m,$d_d,$index){
$html=str_replace('$ymd=array($d_y,$d_m,$d_d,$u_h);?>'.PHP_EOL,"",mb_strstr(file_get_contents("../../../Diary/${d_y}/${d_m}/${d_d}.php"),'$ymd=array($d_y,$d_m,$d_d,$u_h);?>'));
if(strpos($html,'<?php if((new Datetime(date')!==false){
$html=strstr($html,'<?php if((new Datetime(date',true);//時限記事部分を消す(ソース見られたら内容がばれちゃう)
}
$html=str_replace('<?php $count++; echo img(', "", $html);//理由は不明だがstrip_tagsで誤動作が起きるので...
$html=str_replace('0);?>', "", $html);//最後の大なりが残っちゃうので雑に。一致するやつはたぶんないっしょ・・・・・・
?>
<meta name="twitter:card" content="summary" />
<meta name="twitter:site" content="@trc_vla" />
<meta property="og:url" content="<?php echo"../../../Diary/${d_y}/${d_m}/${d_d}.php";?>" />
<meta property="og:title" content="<?php echo $index[$d_d+0][0];?>"/>
<meta property="og:description" content="<?php echo str_replace('"','\"',strip_tags(str_replace(PHP_EOL," ",$html)));?>" />
<meta property="og:image" content="<?php echo snsImgURL($d_y,$d_m,$d_d);?>" />
&lt;?php
}
function snsImgURL($d_y,$d_m,$d_d):string{
$d=$d_d+0;
if(file_exists("../../../Diary/${d_y}/${d_m}/Pictures/${d}_1.jpg")){return "https://trc-vlackhistory.net/Diary/2019/01/Pictures/${d}_1.jpg";}
if(file_exists("../../../Diary/${d_y}/${d_m}/Pictures/${d}_1.png")){return "https://trc-vlackhistory.net/Diary/2019/01/Pictures/${d}_1.png";}
//もし画像がない場合
return "https://trc-vlackhistory.net/title.png";
}
こういう雑な実装になってます(笑)
is_displaying_on_index()に関しては、トップページで使ってるファイルの再利用です。
二重にファイル探索することになるんですけど、このスパゲッティーコードでそんなこと気にしてもしょうがないので諦めました。
動けばいいんだよ動けば・・・・・・。
rawText()に関してはだいぶ雑な実装です。僕が正規表現を上手く扱えなかったのが原因です(笑)
リファレンス通りに打ち込んだはずなんですけど、エスケープとか多すぎてぐっちゃぐちゃになるので諦めてものすごい雑に仕上げました。言うて最初の100文字程度がちゃんと入れば後はなんだってよかったので・・・・・・。
トップページの更新箇所に関しては、めっちゃ地味な変更しかしてないのでソースコードは載せませんけど、相対パスがズレるので、フラグを見てそれを管理するようにすべてのリンクに変数を噛ませて、あと同様に「1日前を読み込む」ボタンに新たにパラメータを付与してなんとか動いてるチックな体裁を整えました。
これにより、twitterからリンクを踏むと、3日間はトップページに飛ばされますが、それを過ぎるときちんと記事ごとのページに飛んでる
ように見えるページが完成し、おかげでそれぞれのページに独立してmetaタグを埋め込むことができるようになりました、めでたしめでたし、と。
読み込むファイル自体は新しくなっていないので、日記ファイル内容を一括で書き換えれば2018年以前の日記にも適用できるはずなんですが、特に意義もないのでやめときます笑
久々に日記のプログラム触った気がしますけど、ほんんっっっっっとに管理しづらい・・・・・・笑
あ、もしかしたらどっかバグってるかも知れないんでリンク切れとかあったら教えてください(笑)