ブログ投稿確認画面の仕様はこんなの

WordPress のデータベースとアップロードされたファイルとで、動的にHTMLを作る仕組みです。
ということは、HTMLの元になるデータが、データベースとファイルにある、ということ。

WordPress が使用する各テーブルの内容に関しては、ネットにいくらでも情報があるので、そっちを参照してもらうといいでしょう。

6月末までに私が作成したブログ投稿を確認するための仕組みはこんな感じで動作してます。

(1) まず、webroot のディレクトリ
このブログサーバーに落ち着くまで、過去にいろいろな経緯があったと思います。
そして、担当者も何人も変わったと聞いています。
そのせいか、webroot になっているディレクトリには、今も使われている WroedPress を設定した
ディレクトリを含めて、かなり多くのディレクトリがあります。
大学なんで、誰でも簡単に情報発信できるのがいいところ、と言えば聞こえはいいのですが…
ディレクトリだけで3桁に迫る数がありました。

ということで、まずは webroot にあるディレクトリのリストを作ることから始めます。
もちろん、webroot にはいろいろなファイルが置いてあるので、ファイルタイプを調べて、それらをチェックしていきます。

具体的には、dir() の結果を read() で順番に読んで、2次元の配列を格納していきます。2次元にしたのは、ファイル名とディレクトリかどうかのチェックを同じ添え字番号でアクセスできるようにするため。PHPはこういうのを簡単に作れるのいいですよね。

実際に使っているのはこんなコードです。
if( is_dir( $this->prefix_dir ) ) {
  if( $dh = opendir($this->prefix_dir)) {
    while(( $file = readdir($dh)) !== false ) {
      $this->dir_list[$this->dir_count]['name'] = $file;
      $this->dir_list[$this->dir_count]['type'] = filetype($this->prefix_dir . $file);
      $this->dir_count += 1;
    }
  }
}

(2) 次に WordPress 用のデフィレクトリか確認を
webroot にあるディレクトリのリストができたら、その中に、wp-config.php があるか確認していきます。
(1) で作った配列にをループで回して、ファイルチェックを行い、見つかったら内容を読んでこのファイルに書かれたデータベース名を配列に格納していきます。これで、このサーバーで公開している WordPress のリストができあがりです。

if(strcmp($this->dir_list[$i]['type'], "dir") == 0 ) {
  $config_file = $this->prefix_dir . $this->dir_list[$i]['name'] . "/wp-config.php";
    if( is_file($config_file)) {
      $this->dir_list[$i]['wp_chk'] = 1;
      $cf_lines = file($config_file);
      foreach( $cf_lines as $line ) {
        if($startpos = strpos( $line, "DB_NAME") !== false ) {
          $endpos = strpos($line, ");");
          $length = $endpos - 20;
          $this->dir_list[$i]['dbname'] = substr($line, 19, $length);
          break;
        }
      }
    }
  }
}

実は作りかけのブログ記事がありました。wp-config.php はあるのですが、そこに記載されたデータベースは MySQL にありませんでした。過去の担当者が何かやったのでしょうが、こういうのは無視するしかありません。

(3) ブログサイトの情報をデータベースから
WordPress の場合、ブログサイトの名称やURLなどは、MySQL のデータベースに記録されています。
これらを参照して、WordPress の基本情報を完成させます。基本情報は、最初に作ったディレクトリの
配列に記録していきます。
PHPでは、こういう中途半端な配列を気にせずに使えるのがいいですね。

例 WordPressのディレクトリの場合
  $datas[0]['directory'] = "xxxxx";
  $datas[0]['dir_flg']   = 1;   // dir_flg が1ならディレクトリ、0ならファイル
  $datas[0]['wp_flg']    = 1;  // wp_flg が1なら WordPress用、0なら別のディレクトリ 
  $datas[0]['database']  = "xxxxx";

例 WordPressではないディレクトリの場合
  $datas[1]['directory'] = "yyyyy";
  $datas[1]['dir_flg']   = 1;
  $datas[1]['wp_flg']    = 0;  // WordPressのディレクトリではない。
                  $datas[1]['database'] が無くても問題なし

例 webroot にあるファイル
  $datas[2]['directory'] = "robots.txt";
  $datas[2]['dir_flg']   = 0;  // テキストファイルなので対象外
                  $datas[2]['wp_flg']などが無くても問題なし

WordPress が扱うデータベース内は、wp-config.php で指定した接頭子を使ったテーブルの名称が使われます。偶然、新規登録する際にこの接頭子を共通にすること、というルールがあったので、全て同じテーブル名で参照できました。とはいえ、ルールがはっきりしているので、合成するのも簡単です。

ブログ名称などは、(接頭子)_option というテーブルに入っています。このテーブルは、

例 接頭子が「wp_」だった場合は、テーブル名は「wp_option」

になります。

内容はこんな感じで、option_name に入っているキーワードを使って、option_value の値を取り出す
ようなSQLを組みます。

option_id   (ユニークなIDが振られています)
option_name  (システム内で使用する blogname などのキーワードが格納されてます)
option_value  (キーワードに対応する具体的な URL などの文字が格納されてます)

例えば、ブログの名称は、こんなSQLで取り出せます。

select option_value from wp_option where option_name = 'blogname';

(4) 投稿した記事は、(接頭子)_postにある
ブログの情報が解ったので、次にそれぞれのブログに投稿された記事を調べます。記事専用の別の配列を用意して、まず、ディレクトリ用の配列から必要な情報をコピーします。このコピーする情報は、扱う数が多ければ配列の番号だけを格納して後から参照するべきですが、今回作る仕組みは扱う数が少ないので、全てコピーすることにしました。また、同じテーブルには、記事に貼り付けるためにアップロードした画像の情報も入っています。これも別の配列に格納します。

全データを取り出す必要はなく、今回作成したページでは1週間分に限定しています。

(接頭子)_postのテーブルに格納される記事は、下書きした分や、保存したものが全て格納されているので、以外とたくさんあります。このうち、「post_date」列に投稿した日時が格納されているので、1週間分を取り出す際は、ここをSQL分の where で指定します。

また、下書きや保存のみ、画像などと公開された記事の区別は、「post_status」の列で判定しました。
なお、画像データは、添付された記事のIDが格納された「post_parent」列を参照し、さらに「post_type」で添付データと判定してます。

使っているSQLはこんなので、特別なことはやってません。

1週間分の記事を抽出するSQL
select id,post_title,post_date from wp_posts 
  where ( post_date between '2016-6-20' and '2016-8-27' and ( post_status='publish' );

指定する記事に添付された画像などを抽出するSQL
select id, post_name, guid from wp_posts 
  where ( post_parent = '100' ) and ( post_type = 'attachment' );

SQLでデータベースから取り出したデータを各配列に格納したら準備OKです。

(5) 表示するデータを作成する
(4)までの処理で配列に格納したデータを使い、表示するデータを作成します。表示は、1日分なので、各記事のDBから「post_date」をコピーした日付データを確認し、その日に投稿された記事を表示用の配列にコピーしていきます。画像では、その日に投稿された記事のIDを使い、その記事に貼り付けてある画像を parent_id を調べて該当するデータを、別に用意した画像表示用の配列にコピーします。

表示用のデータを作ったら、それをHTMLの表形式で表示します。画像に関しては、ファイルをサイズを
予め調べておき、それを表示する記事毎、日毎に集計してHTMLに書き出します。また、ここの画像は縮小版のファイル名を調べてそれを表示し、元の画像は jQuery を使った Lightbox で、ここの画像のファイルサイズといっしょに表示するようにしてます。なお、Lightbox では、記事毎にグループを作ってスライドショーで確認できるようにしてみました。

Lightboxが表示する画像のURLは次のとおり。
<a href="http://(ブログ記事のURL)/wp-content/uploads/(元の画像データ)"
data-lightbox="image[200]" title="File size (ファイルサイズ数)byte ">
<img src="http://(ブログ記事のURL)/wp-content/uploads/(縮小してアップされた画像データ)">
</a>

ディレクトリを調べてブログかどうか判定し、ブログだったらデータベースを参照する、という仕組みはそれなりに作るのに手間がかかりました。また、データベースに格納されたURLからファイルのパスを作ってファイルサイズを調べるといった処理も正直手間取りました。表示については、どの日の投稿で大きなファイルをアップしたか、が解ればいいので、かなり手を抜いてます。そっちを凝ればさらに時間がかかるのでしょう。最後に、Lightbox の設定は一番簡単でしたが、見栄えはばつぐんです。やっぱりきれいに見えるページはできがよく見えますね。

以上