Windows Vista 上でMoodle 1.8を搭載してみました。既にこのサイトで議論なされている若干の文字化け対策を施せば、とりあえず問題なく動作しているようです。ただ、Windows Vistaでは、セキュリティがいままでのWindowsよりは一応しっかりしているようで(おそらくUnix/Linuxに近い趣がある感じです)インストールは若干試行錯誤が必要でしたので、インストール方法をまとめてみました。少し厚かましいかなぁと思いつつ、ご参考までに私の個人的な方法を下記のリンクでご紹介させていただきました。
すみません。個人的なHP上です
ここに集う皆様がたならとっくにご承知かとは思いますが、その際には笑って無視してください。
非常に分かりやすい詳細なインストール方法をありがとうございます。
下記Moodleドキュメントの「インストール」に松村先生のドキュメントへのリンクを追加させて頂きました。
http://docs.moodle.org/ja/管理者ドキュメント
当方の環境は行き当たりばったりで対策を施してきたため,自分のシステムがどういう経緯を経て現状に至ったのか分からなくなりつつあったので,moodle1.8の新規インストールのためのドキュメントはとても頭の整理をするのに役立ちました.
松村先生のドキュメントを読んでいて気付いたのですが,日本語ファイル名のためのパッチについて言及されていますよね.同じ対策を当方でも以前に行なっていたのですが,いつの間にかWeeklyのアップグレードを行なっているうちにmoodleオリジナルのファイルで上書きしてしまっていたようです.改めて対策し直しましました.
いやぁ,しかしまだ化けますねぇ.Windowsにはムリなのか.
アップロードした日本語ファイル名のファイル,新規作成した日本語フォルダ名のフォルダ.うまくいくものもあれば,化けるものもあり.(例 "実践工業数学参考文献.txt")
それとも松村先生の構築された環境では文字化けしないで上記例のようなファイル名のファイルがアップロードできますか? 化けないようでしたら当方の環境に問題があることになります. 上記例のファイルは,アップロードした後に削除もリネームも出来なくなります.もし試されるのであれば,testなどのANK文字のフォルダを作成後,そのフォルダ内にアップロードして見て下さい.フォルダ丸ごとならば削除できました.
----------------
Windows VistaにPCを更新してからアプリケーションやハードウェアが動かないという話をよく聞きます.移行にはかなり気を使うようですね.当方の環境では三次元CADソフトウェアのライセンスキーであるドングルのドライバーがVistaに未対応のため,OSのバージョンアップはしばらく見送りです.
----------------
ファイル/フォルダのI/Oの根幹になる関数(最終的にはPHPですが)が存在するならば,そこでファイル名/フォルダ名を$localewincharsetに変換すれば良いのかとも考えたのですが,副作用が怖くて手を出せません.
Tatsuya Shirai 様
ご指摘ありがとうございました。
確かに「実践工業数学参考文献.doc」という名前のファイルは、文字化けするだけでなく、アップロードすらできない状態でした。
なんとかfile.phpのプログラムを編集して、とりあえずアップロードだけはできるようになりました。いちおう日本語ファイル名「実践工業数学参考文献.doc」を「8ec091488d488bc690948a778e518d6c95b68ca3.doc」
という16進数の文字コードの列に変換して、アップロードする(定義関数string3hexcodes あるいは組み込み関数 bin2hexを使う)ようにすれば、ともかくもファイルがアップロードでき、かつそのファイルを開いたり、ダウンロードできたりするようにはなりました。(果たして、このような方針で問題解決にいたるでしょうか?)
しかし、まだファイル名が表示できない状態です。アップロードされたファイルは、「_.doc」という名前になって見えています。まぁ、これでもなんとか我慢できないわけではないですが(全くアップロードできないよりは遥かにましです)、
一応、16進数のコード文字列を元の漢字の文字列に変換する関数をも用意できた(つもりです:hexcodes2string)ので、おそらく、どこかこのファイル名を表示する箇所にこの関数を組み込めば、なんとか処理できそうな気はしていますが...。
アップロードファイルの名前を表示する箇所がどこで行われているのかどなたかお教えいただけませんでしょうか?
実は、これまでMoodleのソースコードはほとんど覗いたことがありませんでした。いやそれどころか、私はPHPのプログラミングはまだ全然やったことがなく、この1日,2日大慌てでPHPの勉強をしていた次第です。いまからやっとMoodleのソースを調べてみようと思っているところです。
上のような方針で、なんとかWindowsにおけるアップロード・ファイル名の文字化け対策ができそうでしょうか?お教えを賜れば幸いです。
/moodle/file.php のファイルの次のフラグメントを次のように修正しました。
そして下記のようなユーザ定義関数を追加しました。
// ========================================
// finally send the file
// ========================================
session_write_close(); // unlock session during fileserving
$filename = $args[count($args)-1];
////// ここに次の13行を挿入
$ua = $_SERVER['HTTP_USER_AGENT'];
if (strstr($ua, 'MSIE') && !strstr($ua, 'Opera')) {
$enc = "ISO-2022JP";
$name = get_name($filename,$enc);
$new_name = bin2hex($name); // 'bin2hex' seems to work the same way as 'string2hexcodes'.
$extension = get_extension($filename,$enc);
$filename = $new_name.".".$extension;
} else if (strstr($ua, 'Safari')) {
$filename = "";
}
$filename = str_replace('#', '%23', $filename);
//////
send_file($pathname, $filename, $lifetime, $CFG->filteruploadedfiles, false, $forcedownload);
.... 以下省略
///// 追加されたユーザ定義関数
function get_name($filename,$enc) {
$_pos=mb_strrpos($filename,".",$enc);
return mb_substr($filename,0,$_pos);
}
function get_extension($filename,$enc) {
$len = mb_strlen($filename);
$_pos=mb_strrpos($filename,".",$enc);
$pos1 = $_pos+1;
$len1 = $len-$pos1;
return mb_substr($filename,$pos1,$len1);
}
/*
function string2hexcodes($str,$enc) { //// 'bin2hex' seems to work the same way as this function.
$len = mb_strlen($str,$enc);
$code[$len];
$strX = $str;
for($i=0; $i<$len; ++$i) {
$_char = mb_substr($strX,0,1,$enc);
$char_code = ord($_char);
$code[$i] = dechex($char_code);
$len1 = mb_strlen($strX,$enc)-1;
$strX = mb_substr($strX,1,$len1,$enc);
}
$strX="";
for($i=0; $i<$len; ++$i) {
$strX = $strX.$code[$i];
}
return $strX;
}
*/
function hexcodes2string($codestr) {
$len = strlen($codestr);
$chars[$len];
$codestrX=$codestr;
for($i=0; $i<$len; ++$i) {
$lenX = strlen($codestrX);
$char1 = substr($codestrX,0,1);
$char2 = substr($codestrX,1,1);
$num1 = get_code($char1);
$num2 = get_code($char2);
$chars[$i] = chr($num1*16 + $num2);
$len2 = $len-2;
$codestrX = substr($codestrX,2,$len2);
}
$strX="";
for($i=0; $i<$len; ++$i) {
$strX = $strX.$chars[$i];
}
return $strX;
}
function get_code($char) {
switch($char) {
case "0": return 0;
case "1": return 1;
case "2": return 2;
case "3": return 3;
case "4": return 4;
case "5": return 5;
case "6": return 6;
case "7": return 7;
case "8": return 8;
case "9": return 9;
case "a": return 10;
case "b": return 11;
case "c": return 12;
case "d": return 13;
case "e": return 14;
case "f": return 15;
default : return 0;
}
}
松村先生の環境でも日本語ファイル名の文字化けが発生するという報告を聞き,安心しました.うーん,Windowsサーバを使用している英語圏以外の方々は困っていないのでしょうか...
とてもパワフルな解決策ですね.
私も同じようにファイル/フォルダを操作する根本となる関数に手を加えて,現状のファイルシステムに合わせた文字コードへ変換したらどうかと考えていました.松村先生は16進コードですね.私はS-JISへの変換を考えていました.書き込むときはS-JISへファイル名/フォルダ名を変換し,読み出す時/参照する時はファイル名/フォルダ名をUTF-8に変換する.ただ,どこから手をつけてよいのか分かりませんでした.
あまり深い部分のコードに手を入れると,何か副作用が発生するのではないかと心配ですよねぇ.
添付した画像は”参考”というフォルダと"ankANK123"というフォルダを以下のコードを追加した状態で作成した場合の表示結果です.
$name = rawurlencode($name);
if (file_exists("$basedir$wdir/$name")) {
フォーラムにファイルを添付する場合はどうなんだろうか,などなど考えると先が心配ではありますが,単にファイルをアップロード,ダウンロードするだけならば悪くないかも?
P.S. 親フォルダよりも上に表示されてしまうのが小さな悩みですね
さらに加えて,
function displaydir ($wdir) の760行目あたり,
$filename = $fullpath."/".$dir;
$fileurl = rawurlencode($wdir."/".$dir);
$filesafe = rawurlencode($dir);
$filesize = display_size(get_directory_size("$fullpath/$dir"));
$filedate = userdate(filemtime($filename), "%d %b %Y, %I:%M %p");
print_cell("center", "<input type=\"checkbox\" name=\"file$count\" value=\"$fileurl\" />", 'checkbox');
print_cell("left", "<a href=\"index.php?id=$id&wdir=$fileurl&choose=$choose\"><img src=\"$CFG->pixpath/f/folder.gif\" class=\"icon\" alt=\"$strfolder\" /> ".htmlspecialchars($dirdecode)."</a>", 'name');
マルチバイトなファイル名,フォルダ名はUTF-8にするのではなく,全てrawurlencode()してファイルシステムに保存し,rawurldecode()で表示する,という考えです.
やはり親フォルダ,よりも上に(参考という名前のフォルダが)表示されてしまうのは同じですが...なんとか回避する方法もあるかな?
rawurlencode()されたファイル名/フォルダ名ならばファイルシステムにも負担が少ないですし,S-JISしか対応していないアプリケーションでも安心して(ファイル名に%を含むのが不安ですが,大丈夫でしょう)操作できますね.エクスプローラで見ても何のことやら分からないのは,UTF-8でも同じですし.
まだフォルダ作成でしか試していません.削除はこのまま手を入れずに対応可能,リネームもそれほど難しくないでしょう.ファイルの一覧表示もフォルダの一覧表示とほぼ同じコードで書かれているようですので大丈夫でしょう.
ファイルのuploadに関しては,まずクライアントのファイル名を取得した後,それをrawurlencode()したファイル名にリネームしてサーバに保存する必要がありますねぇ.ちょっとここは先送り.
moodle/lib/uploadlib.phpのfunction preprocess_files()の142行目あたり,
$newname = rawurlencode($newname); // (追加)
if ($newname != $this->files[$name]['name']) {
$a->newname = $newname;
$this->files[$name]['uploadlog'] .= get_string('uploadrenamedchars','moodle', $a);
これで一応,表面上は全て問題ないように見えますが...ファイルやフォルダをリンクしたときに正しく動くか,正しく表示されるか,という点に大いに疑問がまだ残っています...
いくつか上記以外の修正を行ないましたが,いまのところ問題ありません.リソースへのリンクなど,うまくいくかどうか(主に表示上の問題だとは思いますが)調べる必要があります.
この改造はあくまでファイルシステムがWindowsの場合にのみ意味がある変更です.
(Linuxでも文字コードに左右されないという点は意味があるかも知れません)
来週末の学会発表の準備もありますので,検証作業については一時中断しますが,また再来週辺りに作業を再開しようと思います.
P.S. 試験的にイジくったもので,非常に汚らしいのですが,現状のfiles/index.phpとlib/uploadlib.phpの改造後のものとオリジナルを添付します.moodle1.8+用です.興味がある方は試してみて下さい.
なにせ2月からmoodleを触り始めて初めてUTF-8の存在を知ったくらいですので(unicodeはまさにユニ(単一の)コードだと信じていました),UTF-16が何なのか,(いまWebで調べてみましたが)分かりません...UTF-16はWindowsでファイル名として扱い易いのですか?
しかしここでフッと冷静になって考えてみると,rawurlencode/decodeではなく,Shift-JISに変換すれば良かっただけではないか?という素朴な疑問が湧いてきました.
いまrawurlencode()しているところを,mb_convert_encoding($str, 'UTF-8', 'CP932'):うろ覚え,その逆もしかり.そうすれば日本語Windowsのファイルシステムとは親和性が高いですね.もちろん,S-JISに存在しない文字は正しく変換されないなどの問題点もありますが...
なんにせよ,既に存在する日本語ファイル名のフォルダやファイル名(うちは幸いなことに日本語禁止にしていますのでほとんどない)は変換が必要ですので,いずれかの方針を早めに決めるか,あるいはいずれにも対応できるように工夫する必要がありますね.簡単にフラグで切り替えられると便利そうですが,私には荷が重いです.
どの箇所を修正すれば良いのかを洗い出し終われば,各ファイルシステムに適した修正方法を選択できると思いますので,少しずつ整理していきましょう.いやいや,まずは本業を...
少々話は変りますが,
Wikiを使用していて気付いたのですが,新しいリンクが日本語の単語だと,これも化けます.データベースに保管しているならばWindowsのファイルシステムの影響は受けないと思っていたのですが,moddata/wikiの下に文字化けしたファイルとフォルダが...データベース内に保存していたわけではないのですね(完全な裏づけは取っていません).
moddataの下を見るとかなり悲惨ですねぇ.forumというフォルダの中にも添付ファイルと思われる文字化けした日本語ファイル名のファイルがあります.
こういうところまで考えると絶望的な気持ちになります...OSをLinuxにすれば解決するのですものねぇ.ユーザに対して,フォーラムへの添付ファイルだけは日本語禁止!とも言えませんし.
いや本当に,これは日本語windows以外のWindowsでは問題になっていないのでしょうか?
Moodleが(というよりはPHPが)どういうふうにファイルシステムにアクセスしているかによって,Shift JISで渡すべきかUTF-16で渡すべきかが決まるのかもしれません。
嘘を書いているかもしれないのでご注意ください。
http://www.microsoft.com/downloads/details.aspx?FamilyID=8c4e8e0d-45d1-4d9b-b7c0-8430c1ac89ab&DisplayLang=ja
同じサーバ上で他に物理シミュレーションソフトウェア用のライセンスサーバを動かしている関係から,このWindowsPC全体のロケールを変更する訳にはいかなかったのですが,PHPだけロケールを変更できるならば,それは一つの解決になるのかも知れません.しかし,勇気が...ないです.
表示される文字だけ直って,ファイルシステムには何の影響も無いという可能性があります.実際に使用した方々の書き込みを見ても,画面上の文字表示や文字入力が可能になったという報告ばかりですし,apache/phpに対して適用してうまく行ったという報告は発見できません.
http://www.okisoft.co.jp/esc/cygwin-20.html
こちらのページが参考になるかと思います.
これを読んで,ロケールさえ変更できればうまくいくのではないかと考えたのでした.
”UTF-8 Cygwin の実体である改造版 cygwin1.dll”
なんとなくプンプンと危険な(良い)臭いがしますね
Windows XPまでは16ビットのUnicode(UCS-2)というレベルの対応だろうと思うのですが,VistaからUTF-16のsurrogate pair対応(一部の文字は32ビットで表す)になり,さらに複雑になったようです。文字セットがどんどん大きくなるのに,いまだにアプリケーションがShift_JISで止まっているのが問題なんでしょうね。
MoodleをWindowsで動かしたい人はこれからますます増えるでしょうから,Moodle側で(あるいはWindows版PHPとも合わせて)対応する必要が出てくるだろうと思います。残念ながら私はWindowsをふだん使わない人間なので,よくわからないことが多く,Windowsに詳しい人が考えてくださることを期待しています。
# 一方で,Windows捨ててMac miniあたりで,という動きが出てもおもしろいと思いますが。
http://moodle.org/mod/forum/discuss.php?d=71413#p319955
短時間の作業で,S-JISでのフォルダ作成がうまくいってかなり大喜びしたのですが,その後,rawurlencode版では問題にならなかった箇所で問題が発生してしまいました.原因はマルチバイトの場合にのみ発生することでしたので,細部の理解が必要であるため,一時pending(変な表現です)としました...