2の問題の対策1と対策2を考えてみました.Moodle1.8.3+用です.
(対策1)閲覧はできるが編集はできない改造:
lib/flielib.phpのfunction send_file()の後半(430行あたり),
if (empty($filter)) {
if ($mimetype == 'text/html' && !empty($CFG->usesid) && empty($_COOKIE['MoodleSession'.$CFG->sessioncookie])) {
//cookieless mode - rewrite links
@header('Content-Type: text/html');
$path = $pathisstring ? $path : implode('', file($path));
$path = sid_ob_rewrite($path);
$filesize = strlen($path);
$pathisstring = true;
} else if ($mimetype == 'text/plain') {
// @header('Content-Type: Text/plain; charset=utf-8'); //add encoding
@header('Content-Type: Text/plain; charset=sjis'); //add encoding
} else {
@header('Content-Type: '.$mimetype);
}
@header('Content-Length: '.$filesize);
while (@ob_end_flush()); //flush the buffers - save memory and disable sid rewrite
if ($pathisstring) {
echo $path;
} else {
// readfile_chunked($path);
$contents = mb_convert_encoding(file_get_contents($path), 'UTF-8', 'auto');
echo $contents;
}
2種類の改造方法を示しているので注意して下さい.赤とピンクは同時に行ってはいけません.
赤文字の修正を行うことでシフトJISのテキストファイルはそのままで表示できますが,この赤文字の改造だけではUTF-8のテキストファイルは文字化けしますので,ファイルの文字コードに応じてcharsetを変更する必要があります.一番,影響の少ない改造です.
ピンクの修正は少し影響の多い修正です.readfile_chunked($path) は指定されたファイルを1MBごとにバイナリーモードで読み出して送信する関数です.これを用いずに,file_get_contents()関数で一気にテキストファイルを読み出してUTF-8にエンコードしています.(たとえば100MBのテキストファイルを表示しようとすると,少なくともサーバは100MBのメモリを使ってしまうなど,パフォーマンスに悪影響のでる可能性があります)
(対策2)閲覧も編集もできるがダウンロードすると問題がある改造:(の亜流)
こちらの対策は少し利用者に慣れを要求しますが,このくらいの手間をお願いして”文字コードが複数存在するんだ”ということを理解して頂いた方がシステム運営上は好ましい気がします.なお,”閲覧も編集もできるが”とは一部異なります.
アップロードした直後に閲覧すると文字化けが発生します.ただし,”編集”画面に行くと文字化けが”直ります(UTF-8へ自動変換しています)”.そのまま”変更を保存します”をクリックして貰えば,UTF-8に変換されたテキストファイルが上書きされます.したがって,この編集後のテキストファイルをクライアントPC側にダウンロードすると,文字コードはUTF-8に変わっています.
files/index.phpの460行近辺,
case "edit":
html_header($course, $wdir);
if (($text != '') and confirm_sesskey()) {
$fileptr = fopen($basedir.'/'.$file,"w");
$text = preg_replace('/\x0D/', '', $text);
fputs($fileptr, stripslashes($text));
fclose($fileptr);
displaydir($wdir);
} else {
$streditfile = get_string("edit", "", "<b>$file</b>");
$fileptr = fopen($basedir.'/'.$file, "r");
$contents = fread($fileptr, filesize($basedir.'/'.$file));
if (($enc_str = mb_detect_encoding($contents)) != 'UTF-8') $streditfile .= '<BR><small>(文字コードを'.$enc_str.'からUTF-8に変換しました)</small>';
$contents = mb_convert_encoding($contents, 'UTF-8', $enc_str');
fclose($fileptr);
if (mimeinfo("type", $file) == "text/html") {
$usehtmleditor = can_use_html_editor();
} else {
$usehtmleditor = false;
}
$usehtmleditor = false; // Always keep it off for now
print_heading("$streditfile");
何も表示しないと文字コードの変換に気付かないと思うので,編集ファイル名の表示に少し手を加えてみました.
個人的には(対策1)のピンクと(対策2)の組み合わせが良いと思います.なお,テキストファイル以外に影響を与えることは無いと思いますが,完全にチェックしたわけではありませんので,御注意下さい.