”メッセージ”のSubjectはどこまで?

”メッセージ”のSubjectはどこまで?

- Tatsuya Shirai の投稿
返信数: 2

http://moodle.org/mod/forum/discuss.php?d=112262 こちらのディスカッションの続きです.

 Moodleのメッセージ機能で電子メールを送る際,画面下の入力ボックスに入力したテキストから,なんらかのルールに基づいて電子メールのSubjectとしているらしい.当初はメッセージに第1行がSubjectになるものだと勝手に確信していたのですが,どうやら異なるようで,先ほども物凄く長いSubjectのメールが届きました.
(QuickMailブロックを利用している場合はSubject入力欄があるのでこの問題は生じない)

 調べてみました.

 email_to_user()で電子メールを送る直前にSubjectを生成しています.

 message/lib.phpのfunction message_post_message(),

            $messagesubject = preg_replace('/\s+/', ' ', strip_tags($message)); // make sure it's all on one line
            $messagesubject = message_shorten_message($messagesubject, 30).'...';

ここです.$messageはどうやらメール本文全文のようです.空白文字(改行文字も含む)を全て' 'に置き換えた後に,message_shorten_message()関数でSubjectを作っていると思われます.当然,引数の30は,”最大で30文字”と思いきや,実は違いました.

 function message_shorten_message()の2つめの引数である$minlength,そう,”少なくとも30文字”(正確にはUTF-8で少なくとも30byte)という意味でした.少し長いですが,下に全文を掲載します.
 ルールは,
 (1)メール本文が30byteに満たないならばすべてSubject
 (2)30文字(minlegth)を越えた後に'.'か' '(半角ピリオド,半角空白)が存在したらそこまでをSubjectとする.
です.'<'と'>'で括られた'.'と' 'を無視するなど少々の例外はあり.

function message_shorten_message($message, $minlength=0) {
    $i = 0;
    $tag = false;
    $length = strlen($message);
    $count = 0;
    $stopzone = false;
    $truncate = 0;
    if ($minlength == 0) $minlength = MESSAGE_SHORTLENGTH;

    for ($i=0; $i<$length; $i++) {
        $char = $message[$i];

        switch ($char) {
            case "<":
                $tag = true;
                break;
            case ">":
                $tag = false;
                break;
            default:
                if (!$tag) {
                    if ($stopzone) {
                        if ($char == '.' or $char == ' ') {
                            $truncate = $i+1;
                            break 2;
                        }
                    }
                    $count++;
                }
                break;
        }
        if (!$stopzone) {
            if ($count > $minlength) {
                $stopzone = true;
            }
        }
    }

    if (!$truncate) {
        $truncate = $i;
    }

    return substr($message, 0, $truncate);
}

Tatsuya Shirai への返信

Re: ”メッセージ”のSubjectはどこまで?

- Tatsuya Shirai の投稿

 たとえば以下の図のような入力を行なった場合,送信されるメールのSubjectは以下の通りです.



Subject: 12345678901234567890123456 長いぞ長いぞ長いぞ長いぞ長いぞ長いぞ長いぞ長いぞ長いぞ長いぞ長いぞ長いぞ...


 長いぞ...はタイトルに含めなくても十分だと思うのですが,123...6は長さが26文字,空行は結果的に1文字になるので,長いぞが途切れるまでSubjectになります.さすがにトータル998byteに切っているようですが.

return substr($message, 0, $truncate);
にしてもそうですが,これはとってもラテンなルールとコーディングですねぇ.

 確かに,1行目をSubjectとする,というルールにすると,1行目に改行を入力してメッセージを送ってしまったらSubjectが空白になってしまいますが...でも,Subjectが空白だったら'No subject'とでもすれば良いだけの気がします.

添付 SubjectRule.jpg
Tatsuya Shirai への返信

Re: ”メッセージ”のSubjectはどこまで?

- Tatsuya Shirai の投稿

 これは意外と簡単でした.

 先に挙げました,message/lib.phpのfunction message_post_message()の以下の箇所の修正だけです.

        if ($emailforced || (time() - $userto->lastaccess) > ((int)$preference->message_emailtimenosee * 60)) { // Long enough

            $message = stripslashes_safe($message);
            $tagline = get_string('emailtagline', 'message', $SITE->shortname);

//          $messagesubject = preg_replace('/\s+/', ' ', strip_tags($message)); // make sure it's all on one line
//          $messagesubject = message_shorten_message($messagesubject, 30).'...';
            $messagesubject = explode("\r\n", $message);
            $messagesubject = $messagesubject[0];
            $messagesubject = preg_replace('/\s+/', ' ', strip_tags($messagesubject)); // make sure it's all on one line
            $messagesubject = trim($messagesubject);

            $messagetext = format_text_email($message, $format).
                           "\n\n--\n".$tagline."\n"."$CFG->wwwroot/message/index.php?popup=1";

一行目が空行だったらどうしようとか,そもそも何も入力されなかった場合は?と心配したのですが杞憂でした.頭の空行(半角空白のみの行含む)は捨てられるらしく,さらに全く何も入力されなかった場合はメッセージが送信されないようです.ですので,'(No Subject)'とする必要は無しです.

 fs_moodleではさらにサービスして,[メッセージを送信する]ボタンにマウスカーソルを合わせると添付した図のようにメッセージをポップアップするようにしてヒントを出すようにしました.

#別件で電子メールのログを出力していたのですが,私が予想していたよりも多くの学生がMoodleを介してメール送信を相互に行なっていました.全く紹介していなかったのに.


 なお,メッセージ機能でテキスト入力にHTMLエディタを使用する設定にしている場合,HTMLエディタがたてに大きく場所を取るため,テキスト入力エリアの下のボタン類が画面からハミだしてしまい押せません.これは一番下のフレームのスクロールバーの表示がoffになっているためです.以下のscrolling="no"を"yes"にするとスクロールバーが表示されます.なんで"no"にしてあるのだろう???

message/discussion.phpの58行目あたり(Moodle1.9の場合)

       <frame src="user.php?id=<?php p($user->id)?>&amp;frame=user"     name="user"
              scrolling="no"  marginwidth="0" marginheight="0" frameborder="0" />
       <frame src="messages.php"  name="messages"
              scrolling="yes" marginwidth="10" marginheight="10" frameborder="0" />
       <frame src="refresh.php?id=<?php p($user->id)?>&amp;name=<?php echo urlencode(fullname($user)) ?>"  name="refresh"
              scrolling="no"  marginwidth="0" marginheight="0" frameborder="0" />
      
       <frame src="send.php?id=<?php p($user->id)?>"     name="send"
              scrolling="no"  marginwidth="2" marginheight="2" frameborder="0" />

添付 PostMessageButton.jpg