フォーラムを未読にするか,マークを付ける機能が欲しい

フォーラムを未読にするか,マークを付ける機能が欲しい

- Tatsuya Shirai の投稿
返信数: 5

 出先で未読のフォーラムを読んでしまうと未読のマークが(当然ながら)消えてしまいます.あとで戻ってからゆっくりと返信しようと考えていても,出先から戻るとすっかりそのことを忘れている.

 これを防ぐには以下の4つの方法が考えられる.

  1. 返信を忘れないように何かにメモを残しておく.
  2. ”未読に戻す”機能を追加する.
  3. ”マークを付ける”,あるいは”後で返信する”といったフラグを付ける機能を追加する.
  4. 「出先」チェックボックスをチェックしてログインすると,フォーラムを読んでも未読が解除されない”出先モード”機能を追加する.

 実は4の機能がいちばん簡単に実装できるような気がします.個人的には便利なのですが,多くの方々の共感を得るのに苦労しそうですね.やはり2か3の機能の方がスマートですよね.いかがでしょう?

Tatsuya Shirai への返信

Re: フォーラムを未読にするか,マークを付ける機能が欲しい

- Tatsuya Shirai の投稿

 ちょっと時間があったのでソースを見てみました.

 どうやら,”未読に戻す”機能を将来的に実装する予定が見て取れます.

 ディスカッショントピックの一覧表示から特定のディスカッショントピックを開くには,discuss.phpを呼び出すのですが,その引数にmarkというオプションがあります.$mark == 'read', $mark == 'unread'の2つが選択できそうですが,現状ではこの引数を付けた呼び出し方法が提供されていないように見えます.

    $mark   = optional_param('mark', '', PARAM_ALPHA);       // Used for tracking read posts if user initiated.
    $postid = optional_param('postid', 0, PARAM_INT);        // Used for tracking read posts if user initiated.

でパラメータ,$markと$postid(Discussion IDではなく個別のpostのIDでしょう)を受け取り,

    if ($mark == 'read' or $mark == 'unread') {
        if ($CFG->forum_usermarksread && forum_tp_can_track_forums($forum) && forum_tp_is_tracked($forum)) {
            if ($mark == 'read') {
                forum_tp_add_read_record($USER->id, $postid);
            } else {
                // unread
                forum_tp_delete_read_records($USER->id, $postid);
            }
        }
    }

ここでデータベースの未読フラグを操作しているように見えます.

似たような作業はmarkposts.phpというソースの中にもあります.調査は適当ですが,このソースは,mod/forum/index.phpとmod/forum/lib.phpでハイパーリンク先としてアドレス指定されています.分かりやすい箇所としては,index.phpは添付した図のようにフォーラム一覧表示で”未読の投稿”の数の右にあるチェックをクリックしてフォーラムの未読をすべて既読にする箇所で用いられています.この場合,引数はf=フォーラムID,mark='read'で,フォーラム単位で既読にするオプションのようです.

 仕組みとしてはフォーラム単位,ディスカッショントピック単位,投稿単位での既読,未読をセット/リセットできるようです.ディスカッショントピック単位や投稿単位での未読/既読のセット/リセットの実装が完成していないように見えるのは,まだテストが不十分か,あるいは作業の優先順位が低いのか,はたまた忘れられているのか^^;

 なお,markposts.phpのソースの最後のところには,

     if ($mark == 'read') {
        if (!empty($d)) {
            if (! $discussion = get_record('forum_discussions', 'id', $d, 'forum', $forum->id)) {
                error("Discussion ID was incorrect");
            }

            if (forum_tp_mark_discussion_read($user, $d)) {
                add_to_log($course->id, "discussion", "mark read", "view.php?f=$forum->id", $d, $cm->id);
            }
        } else {
            if (forum_tp_mark_forum_read($user, $forum->id)) {
                add_to_log($course->id, "forum", "mark read", "view.php?f=$forum->id", $forum->id, $cm->id);
            }
        }

/// FUTURE - Add ability to mark them as unread.
//    } else { // subscribe
//        if (forum_tp_start_tracking($forum->id, $user->id)) {
//            add_to_log($course->id, "forum", "mark unread", "view.php?f=$forum->id", $forum->id, $cm->id);
//            redirect($returnto, get_string("nowtracking", "forum", $info), 1);
//        } else {
//            error("Could not start tracking that forum", $_SERVER["HTTP_REFERER"]);
//        }

    }

    redirect($returnto);

青字で表したようにありますので,”未読にする”機能を実装する予定はあるのでしょう.roadmapにはありませんが.

添付 SetUnread.jpg
Tatsuya Shirai への返信

”出先モード”機能あらため”チョイ読み”機能

- Tatsuya Shirai の投稿

 ログイン時の情報として”出先モード”みたいなものを管理するとクッキーを使わざるを得ないので,添付した図のように未読管理されていて,未読のあるディスカッショントピックを開く際に,[チョイ読み]をクリックして開いた場合は既読にしない,という機能を付けた方がメリットも多いかな?と考えて調べてみました.

 まず,ディスカッショントピックをクリックするとdiscuss.phpが呼ばれ,それがmod/forum/lib.phpのfunction forum_print_discussion()を呼ぶ.その中から更にfunction forum_print_post()を呼ぶ.この一番最後のところにある,

    echo '</td></tr></table>'."\n\n";

    if ($istracked && !$CFG->forum_usermarksread && !$post_read) {
        forum_tp_mark_post_read($USER->id, $post, $forum->id);
    }

    return $ratingsmenuused;
}

この青い一行をコメントアウトすれば既読にならないことは確認しました.[チョイ読み]のリンクとしてdiscuss.phpを呼ぶ際にオプションを一つ追加して呼び出してグローバル変数を一つセットし,それが!empty()ならばforum_tp_mark_post_read()を実行しない,という風に実装すればできちゃいそうですね.

 あとは”チョイ読み”という名称が市民権を得られるのか,ですねウインク


 でも実際,フォーラムにバンバンと学生が投稿してくる書き込みを自宅や出先で読んで,それに対して”後で返信しようっと”と考えていて忘れてしまうこと,結構ありませんか? 自宅や出先では”チョイ読み”して余裕があれば返信,時間がなければ後で時間のある時に未読マークを元にして読み直せば良い,というのはかなり便利な気がします.

 ただ,”ちょい読み”,”チョイ読み”,うーん,長いし,英語ではどう表すのか? ”試し読み”でも無いですし,”盗み読み”でも無いし.何かユニバーサルデザインなアイコンを思いつけば,それが一番スペースも取らないので良いのですけれども....

添付 ChoiYomi.jpg
Tatsuya Shirai への返信

Re: ”出先モード”機能あらため”チョイ読み”機能

- Tatsuya Shirai の投稿

 実際には先の例(あれは手書きで”[チョイ読み]”を書き加えた)のように綺麗にタイトルは左寄せ,リンクは右寄せで配置はできません(ですよね? 表の構造は変更したくない).

 となるとタイトルの後に空白を少しだけ追加してリンクを追加する.これが添付した図(3パターン)の一番上です.なお,ここでは未読ではないものもすべて”(チョイ読み)”を付けていますが,実際に実装するならば関係ないものにはリンクを追加しません.
 見て分かるように,タイトルの長さが違うディスカッショントピックが並ぶ訳ですから,かなり鬱陶しい.

 では,顔写真のところにリンクを追加したらどうか.それが真ん中の図.リンクの場所は常に同じところにありますので分かりやすいですね.でも間違えて写真をクリックしてしまいそうです.それに,行間が広がるクセして少し地味ですね.
 顔写真の所にリンクを,と考えたのには訳があります.モバイルモードでは顔写真の表示を(最新版では)完全に止めました.でも表のスタイルはCSSで設定されているらしく,この列を消すのは危険だと判断しました.したがって顔写真分のスペースが無駄に空いていました.ここに(チョイ読み)のリンクを入れたのが一番最後.モバイルモードの場合はここが最適ですね!

 さてさて,モバイルモード時以外(一番上)はどうしたものでしょう.何か良いアイディアは無いでしょうか.

添付 ChoiYomi3Patterns.jpg
Tatsuya Shirai への返信

「チョイ読み」完成

- Tatsuya Shirai の投稿

 先ほど公開しましたfs_moodle3.01.00に搭載しています.

 原理は以前に説明した,function forum_tp_mark_post_read()を”チョイ読みOn”ならばパスする,本当にそれだけです.

 あとは”チョイ読みOnかOffか”をどのように指示し,どのように状態表示するか,を考えただけです.当初は状態を管理するのに$_SESSION変数を使用するつもりだったのですが,プログラムが複雑になってしまいそうだったので,クライアント側から容易に操作可能であるクッキーを利用する方法にしてしまいました.
 機能のOn/Offはモバイルモード,PDF2JPEG機能同様に,画面下部フッターに表示されるボタンを押すことで,いつでも簡単に切り替え可能です(逆にこれが$_SESSION変数を使えない理由).

 いま現在が”チョイ読みモード”かどうかは,フォーラムのディスカッショントピックの一覧が表示されている際に,一番上のところに赤い文字で”チョイ読み中!”と表示されます.結局,これが一番シンプルでした.

 ですので,追加での修正箇所は(1)フッターにボタンを配置(lib/weblib.php)と(2)”チョイ読み中!”の表示(mod/forum/view.php),合計で3箇所だけです.ただ,クッキーの操作などfs_moodle独自の関数を多く用いていますので,ソースリストの差分は示しません.


チョイ読み機能: 出先などで,フォーラムをチェックしたいけれども未読チェックが外れてしまうのは困る場合に使用する機能.”チョイ読みOn”の状態でフォーラムを閲覧しても,未読情報はクリアされません.

添付 TrialReading.jpg
Tatsuya Shirai への返信

Re: 「チョイ読み」完成

- Tatsuya Shirai の投稿

 少し機能を見直したところ,ぐっと使いやすくなりました.

 追加したのは,mod/forum/discussion.phpの冒頭,

    require_once("../../config.php");
    require_once('lib.php');
// (Shirai085): ここから追加
    if (is_trialreading_on()) $CFG->forum_usermarksread = true;
// (Shirai085): ここまで追加

    $d      = required_param('d', PARAM_INT);                // Discussion ID
    $parent = optional_param('parent', 0, PARAM_INT);        // If set, then display this post and all children.

この1行だけです.$CFG->forum_usermarksreadはフォーラム未読/既読のチェックをユーザが行なうか,それとも自動で行なうのかを判断するために用いられるサイト単位の設定値で,この変数をtrueにすると,添付した図のように”未読にする”,”既読にする”の選択肢が各投稿に追加表示されます.さらに,ディスカッションを表示しても自動的には既読になりません.

 is_trialreading_on()は,fs_moodle用に作った関数で,”チョイ読み機能がOn”の場合にtrueを返します.$CFG->forum_usermarksreadは,mod/forum/lib.phpで初期設定されますので,require_once('lib.php')の直後に値を変更し,”チョイ読み中”ならば強制的にtrueにします.

 この追加を行なうことで,一時的に既読/未読をユーザが自由にコントロールできるようになります.ただし,「サイト管理」-「モジュール]-「活動」-「フォーラム」の”投稿を既読とする日数”(forum_oldpostdays)を過ぎた古い投稿は原理的に既読/未読をOn/Offできません.これはMoodleの仕様です.ユーザ毎のディスカッションの未読/既読はデータベース中のmdl_forum_readに一つずつのディスカッションに対して全てが記録されています.既読かどうかはこの項目をサーチして判断します.いつまでも記録を残しておくとデータベースがパンクしてしまうので,一定の日数を経過したデータは破棄する処理が行われているのでしょう.

 本来,この未読/既読をユーザが設定できる機能のOn/Offはサイト単位でしか設定できない機能です.正確には「サイト管理」-「モジュール」-「活動」-「フォーラム」の”投稿を手動で既読にする”であり,デフォルトではOffです.もしOnにすると,ユーザはチェックした投稿を一つずつ”既読にする”をクリックしなくてはならなくて面倒です.このサイト単位の設定をユーザ単位で一時的にOn/Offできるようにした訳です(”未読の管理をするか,しないか”とは別の次元の設定です).でもこの設定,ユーザの好みがあるのだから,本当はユーザプロファイルで選択できた方が良いです.さらに,自動的に既読にしてしまうのはともかくとて,自由に”未読”に戻せる機能は本来のMoodleでも持っていて欲しい機能ですよね.

 さらに,$CFG->forum_usermarksreadをtrueにすれば,以前に”チョイ読み機能”を実現する際に,未読の管理を行なう(既読の管理というべきかな?)関数であるforum_tp_mark_post_read()の呼び出しをパスする必要もありません.そもそものコードが,

    if ($istracked && !$CFG->forum_usermarksread && !$post_read) {
        forum_tp_mark_post_read($USER->id, $post, $forum->id);
    }

このように,$CFG->forum_usermarksreadを含んでいたからです(笑).もっと早く気付くべきでした.

 ”チョイ読み”としては当初,未読フラグをクリアさせない,という思想のみ実装を始めた機能ですが,結局は,ユーザによる手動の既読/未読管理を随時,On/Offできる機能も簡単に組み込むことができました.これで「あ,しまった,チョイ読みをOnにしないでフォーラムを開いてしまった!」とガッカリすることが無くなりましたし,以前に読んだ投稿(設定値,デフォルトは2週間以内)も既読から未読にも戻せます.副作用さえ発生しなければ,フォーラム閲覧の自由度が格段に上がります.

 明日公開予定のfs_moodle3.02.01にはこの機能を組み込みます.


 まとめると,(すみません,調査と並行しながら記述したら長くなってしまいました)

  1. チョイ読みをOn/Offするボタンを画面下に追加して,状態をクッキーで管理する
  2. ディスカッショントピックスの一覧表示画面などに「いまチョイ読み中」かどうかの状態表示
  3. mod/forum/discussion.phpのrequire_once('lib.php');の次の行に,もしチョイ読み機能がOnならば$CFG->forum_usermarksreadをtrueにするコードを1行追加

これだけでOKです.1と2に関しては皆さんが改造しようとするMoodleの思想に合わせて考えれば良いでしょう.3の機能を1行追加するだけで,とても便利になる,これが今回の報告の全てです.なお,3ですが,Moodle1.8とMoodle1.9とでは,require_once('lib.php');の位置が違います.では,lib.phpの最後に3のコードを追加すれば...という考えも頭の片隅を過ぎりましたが,lib.phpはdiscussion.php以外からも呼び出されるので,副作用が発生する恐れがあります.たとえばforum_cron()でも$CFG->forum_usermarksreadを参照しています.こちらに悪影響を与える可能性がありますので,discussion.phpの冒頭が無難です.

 

添付 Toggle_ReadUnread.jpg