前回
本題
今回は過去、高校生の頃に作ったtimestamp.inc.phpというプラグインをサンプルとして解説します。
このプラグインはタイムスタンプを変更することができるものですが、処理の流れとしては、
?plugin=timestamp&page=ページ名
にアクセスするとplugin_timestamp_action()が呼ばれます。
大まかには、
- タイムスタンプ変更画面の表示
- 管理者パスワードのチェック
- 編集/閲覧可能かのチェック
- ファイルの取得
- recent.dat という更新ページのキャッシュ削除 (タイムスタンプを更新してもキャッシュが残っていると更新ページ一覧がそのままになるため)
- タイムスタンプの変更
となってます。
plugin_(プラグイン名)_action()
action関数は return ['msg' => タイトル名, 'body' => HTMLの文字列];
のようにmsgとbodyがキーとなった配列を返して使います。
bodyが空ならば$vars['page']のページが表示される仕様となってます。
timestampプラグインでは、タイムスタンプ変更画面(上記の画像)は以下のようになっています。
$msg = PLUGIN_TIMESTAMP_TITLE; // $msg = "タイムスタンプ"
$body = "";
// ページが指定されている (変更ボタンが押された)
if ($vars['page'] != "") {
[以下略...]
$body = <<<EOD
<h2>ページ: {$vars['page']}</h2>
<form action="?plugin=timestamp" method="POST">
[以下略...]
</form>
<p>現在のページの更新日時: {$y}年{$m}月{$d}日{$h}時{$min}分{$s}秒</p>
EOD;
} else {
[以下略...]
}
return array('msg' => $msg, 'body' => $body);
$bodyは主に複数行の文字列を扱うことができる記述方法「ヒアドキュメント」を使います。<<<EODとEOD;で囲ってあげて代入することで利用できます。
$body = <<<EOD
<h1>見出し</h1>
<p>文章</p>
EOD;
ヒアドキュメントはEODでなくてもEOMやEOTなどでも可能で最初の開始識別子の<<<〇〇〇と最後の終了識別子〇〇〇;が一致していればOKです。
また最後〇〇〇; の終了識別子にインデントやら、コメントですら使うとエラーが発生するので気をつけてください。
管理者パスワードのチェック
管理者パスワードのチェックにはpkwk_login(パスワード)
を使います。
if (pkwk_login($vars["password"]) == false) {
return array('msg' => "エラー", 'body' => "<p>パスワードが間違っています。</p>");
}
編集/閲覧可能チェック
// 編集可能かのチェック
check_editable($vars['page'], true, true);
// 閲覧可能かのチェック
check_readable($vars['page'], true, true);
ページ操作
timestamp.inc.phpでは以下のようにPHP標準関数を使っているのですが...
$filename = "./wiki/" . strtoupper(bin2hex($page)) . ".txt";
if (file_exists($filename)) {
$source = file_get_contents($source);
[以下略...]
file_put_contents($filename, $source);
}
PukiWikiのページはwiki/
ディレクトリ内に保存されており、文字列を大文字16進数にエンコードされた名前のテキストファイルとして保存されていますので、bin2hex()で16進数にしてstrtoupper()で大文字にする必要があります。しかし...!
こんなことしなくてもPukiWiki内部のページ操作の関数を使ったほうがいいでしょう。
上記のコードは以下のように変更できます。
// ページの存在チェック is_page($page)
if (is_page($page)) {
// ページの読み込み get_source($page, $lock = true, $join = false, $raw = false)
$source = get_source($page, true, true); // 3番引数がtrueなのはstringとして取得するため、デフォルトでは1行ずつの配列となる
[以下略...]
// ページを書き込む page_write($page, $postdata, $notimestamp = false)
page_write($page, $source);
}
なお、PukiWiki内部の関数については以下に記載されてます。
またファイル名を収納するにしろbin2hex、strtoupperは使う必要がなくてPukiWikiにはget_filenameというのがありました。
$filename = get_filename($page); // ページのファイル名を取得 (PukiWiki内部関数)
$filetime = filemtime($filename); // ファイルの更新日時を取得
[以下略...]
touch($filename, $filetime); // ファイルの更新日時を書き換え