rNote の検索プラグイン search.php の動作を修正した。

search.php は、各記事の .xml ファイルを全て読み込み検索処理を行うが、その際、 .xml ファイル内のタグの内容だけでなく、タグ自身も検索対象に含むかどうかを選択するフラグがある。

このフラグがデフォルトで true にセットされていた。なので、検索文字列として rNote と入力した場合、全ての記事がヒットしていた。

これでは意味がないので、 記事の .xml ファイルのタグ自身は検索対象から外すよう、フラグを false にした。

ところが、このときの動作として、

  $entry_buf = _file_get_contents(DIR_DATA . $fname);

if(!$this->bSearchTags){

$entry_buf = strip_tags($entry_buf);

というように、 strip_tags() の結果を使用して検索している。これだと、記事内の全てのタグの内容が無条件に検索対象になってしまうので、意図しない結果をもたらす。これではまずい。

そこで、検索対象とするタグを Title, Text, Addition, Keys に限定することにした。それぞれ、記事の題名、本文、追記、キーワードである。

これで、例えば rNote を検索文字列に指定した場合でも、正しく rNote が題名、本文、追記、キーワードに含まれる場合のみヒットするようになった。

この記事のリンク元 | 9 | 8 |

この記事のリンク用URL&トラックバックURL : https://red-souls.jp/ichounoki/rnote/software/20190815_110247206760.htm


cookie の処理の問題、解決 2019-08-14 (水) 18:47:06+09:00

ソフトウェア

もう解決しました(笑)。

管理画面用プラグイン化した rnotepad.php のクラスの冒頭で <script> タグで直書きされていた javascript コードを、丸ごと変数に代入しておき、 disp() メソッドで作られるページの中身に javascript 部分を追加する形にすることで、他のプラグインの実行時に影響しないようにすることができた。

直書きされているとなぜ、動作設定プラグインの実行時にも javascript が出力されてしまうかというと、動作設定プラグインで「この内容で設定する」ボタンを押した場合に、値が post され ranoteadmin.php が読み込み直されるときに、ボタンの表示部分の処理で、全てのプラグインの require_once での読み込み処理が走り、そこで javascript が読まれて出力されてしまっていた。

今回は、これを、 rnotepad クラスの disp() メソッドが呼ばれたときにだけ出力するようにしたので、他のプラグインへの影響をなくすことができたというわけだ。

意外と早く完全な解決方法が見つかってよかった。

同時に、 config.php (動作設定プラグイン)のバグも修正することができた。

こちらは、setcookie() で cookie が設定されたときに、その設定内容がリロードされるまで $_COOKIE に変更内容が反映されないことに気づかず、 filter_input(INPUT_COOKIE,COOKIE_TESTFLAG) を実行して cookie の値を取得してしまっていたため、リロードがかかるまでラジオボタンの位置の変更が反映されなかった。 $_COOKIE[COOKIE_TESTFLAG] で読み取る方法に戻すことで、修正することができた。( setcookie() 直後に $_COOKIE に変更後の値を直接代入しておく処理はオリジナルの状態から書かれていた。)

この記事のリンク元 | 9 | 8 |

この記事のリンク用URL&トラックバックURL : https://red-souls.jp/ichounoki/rnote/software/20190814_184706405292.htm


うーん、困った 2019-08-14 (水) 14:37:23+09:00

ソフトウェア

rnotepad を管理者画面に組み込んだのは良かったが、問題が起きた。

「動作設定」を実現させているプラグイン config.php 内で cookie を使用しているのだが、 setcookie() 関数が動作しなくなってしまった。

理由を調べて分かったが、「setcookie」によると setcookie() は、

ほかのヘッダ情報と同様に、 クッキーは、スクリプトによる他のあらゆる出力よりも前に 送信される必要があります(これはHTTPプロトコルの制約です)。 や タグはもちろん 空白も含め、あらゆる出力よりも前にこの関数をコールするようにしなければなりません。

ということだが、 rnotepad.php では、 javascript を使用している。

それのどこがいけないかというと、 rnoteadmin.php の動作として、管理画面用のプラグインを順にファイルから require_once() で読み込む。そのとき読み込んだプラグイン内に javascript のコードが含まれていると、その場で

<script type="text/javascript"> 〜 </script>

が出力されてしまうのだ。その結果、 setcookie() は失敗する。

動作設定の画面で「この内容で設定する」ボタンを押すと、 config.php が呼ばれ、毎回上のような動作になるので、必ず setcookie() は失敗してしまう。

これを回避するには、先日実装したコールバックプラグインの機能を使い、新たに「 rnoteadmin.php が読み込まれ、管理画面用プラグインが読み込まれる前に実行するコールバック」を追加し実装するしかないが、そうすると、 config.php の処理が2つのファイルに分かれてしまい、見通しが非常に悪くなるのでやりたくない。

いっそ、 config.php の今の実装を見直し、「携帯用ページをテスト」のフラグを他の項目同様 cookie ではなく config.ini を用いるように変更してしまえば cookie を使わないので、とりあえず問題は回避されるが、 cookie を使わずに特定のブラウザからのみ携帯用ページを表示させてテストするという動作を実現させる方法が分からない。それに、 cookie の使用をやめて回避したのでは、今後 cookie を使用したくなったときに困るので、これは単なる逃げであり解決ではない。

う〜ん、これは困った・・・。どうすべきか。

この記事のリンク元 | 10 | 8 |

この記事のリンク用URL&トラックバックURL : https://red-souls.jp/ichounoki/rnote/software/20190814_143723512439.htm


ずいぶん前に一度、この機能を実装した記憶があるのだが、今の rNote を見る限り機能が付いていなかったので、改めて実装した。

今回は、プラグイン機能の拡張から行った。

rNote のプラグイン機能は、基本的に、 PHP で1つのクラスを作ることで行われる。そのクラスには、 exec() というメソッドを実装しておき、クラス名と同名の主ファイル名の php ファイルを plugins/ ディレクトリの中に入れておく。

そして、スキンファイルの中で、 <%=plugin func="呼び出し関数名" opt="呼び出し関数に渡すパラメータ"> タグを書き込んでおくと、その部分が表示されるときに、プラグインが呼ばれる、という作りだ。( func パラメータは無くてもいいが、その場合 exec() メソッドが呼ばれる。)

ただ、このプラグイン形式だと、スキンファイルに記述しておき、そのスキンファイルが表示されるタイミングでしか呼び出すことができない。

今回の場合、「コメントが送信された」というタイミングで、そのコメントに関する情報を管理者にメールする必要があるので、特定の動作をトリガーにして、パラメータを受け取って起動するようなプラグインである必要がある。なので、現状の「スキンに書かれ、スキンが呼ばれるタイミングで実行される」形式では要件を満たせない。

そこで、今回は、 rNote.php 本体に手を入れ、「『コメントが送信された』タイミングで呼び出されるプラグイン」というものを実装した。このように、「ある動作をトリガーとして、その動作が起きた時に呼び出されるプラグイン」のことを、「コールバックプラグイン」と呼ぶことにした。

そして、コールバックプラグインの実装方法は、 rnote_config.php の中に、

$g_strPlugin = array();

array_push($g_strPlugin, array('name' => 'cmntemail', 'instance' => null, 'func' => 'callback', 'type' => 'wbsave'));

のように、呼ばれるプラグインに関する情報をひとまとめにした要素をもつ配列 $g_strPlugin を用意し、その1要素として、 name, instance, func, type を定義し配列 g_strPlugin に追加する。ここで、 name はプラグインのクラス名、 instance は初期値 null 、 func は呼び出されるメソッド名、 type はコールバックプラグインの種類と定義した。現在は、 type は 'wbsave' (コメントが送信され保存されたタイミング)のみが実装されている。

この形式で、 email を送信する cmntemail クラスを記述し、 plugins/ ディレクトリに用意することで実現した。

何度かテストし、問題なく動作することを確認している。

この記事のリンク元 | 9 | 8 |

この記事のリンク用URL&トラックバックURL : https://red-souls.jp/ichounoki/rnote/works/software/20190813_165038581371.htm


rNote は、記事にコメントが付いた場合、有無を言わさず即時公開される。

これでいい場合は構わないのだが、公開して良いコメントかどうかを確認してからOKなら公開するようにした方がよいと思う管理者もいると思う。自分もその一人だ。コメントスパム対策にもなると思う。(コメントスパムがつくこと自体を回避はできないが、スパムだらけの記事にならないように管理することはできる。)

そこで、管理者画面に追加するタイプのプラグインとして一つ、「コメント承認」プラグインを追加した。

このプラグインの実装のために、まず rNote 本体に手を入れ、コメントの内容を保存したログファイルのフォーマットを拡張した。このログファイルは、コメントのつく先の記事1つにつき1ファイル作成され、1つのコメントが1行になるようになっている。1行の形式は、

投稿者名 [tab] mail/url [tab] 本文 [tab] 投稿日時 [\n]

となっていたので、1項目追加し、下のような形式にした。

投稿者名 [tab] mail/url [tab] 本文 [tab] 投稿日時 [tab] コメント承認フラグ[\n]

コメント承認フラグは「0:未承認, 1:承認済み」というフラグとした。

rNote に手を入れた場所はもう1箇所あって、管理者画面用の「動作設定」プラグイン ( config.php )

だ。ここに、「コメントを承認制にするかどうか」のラジオボタンを追加し、状態を保存するため、他の項目と同様に、グローバル変数の配列 $g_config[] に 'confirm_comment' というキーで値を保存するようにした。このフラグの設定状態を見て、 rNote.php 本体でコメントが送信されたときの処理に、コメント承認制であれば先程のコメント承認フラグを 0 にセットし、承認制でなければコメント承認フラグに 1 をセットしてログファイルを書き込むように動作を修正した。

ここまでの準備ができたので、いよいよコメント承認プラグインを書いた。ぷにゅさんが公開されている「Entries List Plug-in v1.01 & rNote LogViewer lot.041025」を参考に実装した。

ぷにゅさんのプラグインでは、コメントのログファイルを一覧表示し、中身を編集したり、ログファイルを削除したりできるようになっているが、自分のプラグインでは、ログファイルの一覧ではなく、コメントの一覧を表示し、コメントごとに「承認・未承認」の状態を切り替えられるリンクをつける形にした。1ページ分の表示件数は、ぷにゅさんと同じ30件にしたが、この30件はログファイルの件数なので、コメントの多く付いた記事があった場合、実際に1ページに表示される項目数は30を超える。

とりあえずこれで安心してコメント管理ができる。

この記事のリンク元 | 9 | 8 |

この記事のリンク用URL&トラックバックURL : https://red-souls.jp/ichounoki/rnote/works/software/20190813_165002332041.htm