moodle(特にWindowsサーバ)で日本語フォルダ/ファイル名を使用可能とする改造

moodle(特にWindowsサーバ)で日本語フォルダ/ファイル名を使用可能とする改造

- Tatsuya Shirai の投稿
返信数: 26
白井です.

ほぼ完成しました.
いま実地で色々とテストをしながら確かめています.

http://www.suzuka-ct.ac.jp/mech/moodle/course/view.php?id=30

ゲストで入室可能です.

”fsconverter:まとめ”のWikiに記載されている”fsconverter修正箇所一覧"にしたがってソースを修正して下さい.これで,日本語フォルダ名/ファイル名をmoodleで(かなり)使えるようになります.ただし,moodle1.8をベースとして開発を行なっていますので,他のバージョンですと修正箇所が異なる可能性もあります.

特に日本語Windowsをサーバとしているサイトではフォルダ名,ファイル名をS-JISでファイルシステムが管理するように設定できますので,エクスプローラを用いてファイルやフォルダの管理を行なうことも可能です(データベースとの整合性を考えるとお勧めはできませんが).

ちなみにWindowsXP ProfessionalをサーバOSとして利用している当方のサイトでは,UTF-8で作成した(つまり化ける)フォルダが原因で定時バックアップに失敗する問題がありましたが,この問題も解決しました.

とりあえずはご報告まで.使い方,メリットなどはまた時間のあるときにまとめます.


修正箇所はかなり多いです.ある程度の覚悟が必要です.
(メリットが勝りますが!)

Tatsuya Shirai への返信

Re: moodle(特にWindowsサーバ)で日本語フォルダ/ファイル名を使用可能とする改造

- Tatsuya Shirai の投稿
上記コース内に,最新のmoodle1.8.1+をfs_converter化したものを置きました.

手作業で修正するよりも試しに使うにはこの方法の方が楽ですね.

現在のmoodleとは別のフォルダに展開し,config.phpをコピーして設定を合わせれば直ぐに試用できる筈です.

Windowsをサーバとして使用している方は,特にお勧めです.
(バグ出しをしたいのでご協力頂けると助かりますウインク

Tatsuya Shirai への返信

Re: moodle(特にWindowsサーバ)で日本語フォルダ/ファイル名を使用可能とする改造

- Tatsuya Shirai の投稿
ちょこちょこと問題が発覚したため修正を行なっています.

1.コースの短縮名にマルチバイトを用いた場合にバックアップ・リストアが正常に機能しない(対策済み)
2.IEでフォルダを開けない(一部,サブフォルダの扱いに問題が残っているが大筋OK)

本サイトへのアクセスがゲストの場合,フォーラムへの書き込みができませんので,期間限定で以下のアカウントを作成しました.自己登録も可能にしました.

アカウント: fsuser
パスワード:fsconverter

http://narita.mech.suzuka-ct.ac.jp/moodle/course/view.php?id=30


Tatsuya Shirai への返信

Re: moodle(特にWindowsサーバ)で日本語フォルダ/ファイル名を使用可能とする改造

- Tatsuya Shirai の投稿
バックアップの処理に未対策の部分がありました.
コースファイルをzipする前に一時フォルダにファイルとフォルダをコピーする単純な処理なので,ファイルシステムに依存しないかな,と思って適用を行なわなかったのですが,時と場合によって問題があったようです.修正箇所を極力少なくしようと考えて意図的に放置していたのですが,安全のために対策を行ないました.

2007年6月27日現在の最新のmoodle1.8.1+をfs_moodle化したパッケージを

http://www.suzuka-ct.ac.jp/mech/moodle/mod/resource/view.php?id=331

の最新版のフォルダに公開しました.

勝手ながら,フォルダ名/ファイル名に半角カッコなどの文字が使用可能とする修正も適用してあります.もし,安全を考えてこの処理を適用したくない方は,lib/moodlelib.php中の4145近辺をオリジナルに戻して下さい.詳しくは以下のフォーラムを参照して下さい.

http://moodle.org/mod/forum/discuss.php?d=74713
Tatsuya Shirai への返信

Re: moodle(特にWindowsサーバ)で日本語フォルダ/ファイル名を使用可能とする改造

- Tatsuya Shirai の投稿
クライアントのWebブラウザがIEの場合にファイルの操作が行えない問題点が多数,発見されました.デバッグ不足でした.全て対策しました.既にfs_moodleを御利用の方は最新版を以下URLよりダウンロードして更新して下さい.

http://www.suzuka-ct.ac.jp/mech/moodle/mod/resource/view.php?id=331
Tatsuya Shirai への返信

Re: moodle(特にWindowsサーバ)で日本語フォルダ/ファイル名を使用可能とする改造

- Tatsuya Shirai の投稿
コースの省略名に日本語を用いている場合,コースの古いバックアップファイル(ZIPファイル)が自動的に削除されない問題点のあることが判明しました.fs_moodle0.7dで,一応,対策は行いましたが,定時バックアップ時に余分なバックアップファイルを自動的に削除してくれるかの確認はまだ行っていません(多分,大丈夫だと思う).

もし5週分しかバックアップファイルを保存しない設定になっているにも関わらず,コースのbackupdataフォルダ内に古いバックアップデータが残っていて,HDDの残量に悪影響を与えている場合は,fs_moodleを0.7dにアップデートして下さい.


(道理で,近頃,HDDの残量が急激に少なくなってきた訳です赤面
Tatsuya Shirai への返信

Re: moodle(特にWindowsサーバ)で日本語フォルダ/ファイル名を使用可能とする改造

- Yuichi Saotome の投稿
#fs_moodleに関しての話はここに書けばよろしいでしょうか?

五月女@信州大学です.

fs_moodleを利用中気づいたのですが,
admin/delete.php中65行目付近
// if (rmdir($fullfile)) { // (FS_CONVERTER)
 if (rs_rmdir($fullfile)) { // (FS_CONVERTER)

// if (rmdir($fullfile)) { // (FS_CONVERTER)
 if (fs_rmdir($fullfile)) { // (FS_CONVERTER)
のtypoではないでしょうか?
fs_moodle07fにて確認しました.

それにしてもfs_moodle良いですね笑顔
すばらしいものを公開していただき感謝します.
私もこれまで独自にMoodleの拡張をしながら日本語ファイル名対応を行っていたのですが,
WindowsXP&VistaからMacOSX,Firefox,Safari,IE6,IE7の混在環境への対応で頭を悩ませていました.
さきほどからfs_moodleを触らせていただき,出来が良いので感動しました.
ただ,何件か不具合も見つけてますので.またご連絡させていただきます.
Yuichi Saotome への返信

Re: moodle(特にWindowsサーバ)で日本語フォルダ/ファイル名を使用可能とする改造

- Tatsuya Shirai の投稿
ご報告ありがとうございます.はい,ケアレスミスです.危ない,危ない!赤面
その部分は先日,改造した場所ですね.実はどのような条件下で実行される関数かはっきりと分からない(多分,コースをバッサリ消すような場合?)ので,実際に動作確認はしていませんでした.助かります!
他の不具合もご報告お願いします.

Tatsuya Shirai への返信

Re: moodle(特にWindowsサーバ)で日本語フォルダ/ファイル名を使用可能とする改造

- Yuichi Saotome の投稿
五月女@信州大学です.

fs_moode0.7f上でいくつかのパターンか試してみた所,次のような問題がありました.
再現環境は,

* クライアント
o MacOSX10.5 firefox2
o MacOSX10.5 Safari3
o WinXP IE6
o WinXP firefox2
* サーバ
o CentOS 4.5 2.6.9-55.0.9.ELsmp
o PHP 5.2.4
o Apache 2.2.6
o MySQL 5.1.22-rc
* fs_converter
o $fsCFG->fsCharset = 'UTF-8';
o $fsCFG->oldfsCharset = 'UTF-8';

となっています.
試したパターンは

1. MacOSX 10.5でファイル・ディレクトリ作成,標準機能で圧縮,Safari3でアップロード,fs_moodleで展開
2. MacOSX 10.5でファイル・ディレクトリ作成,標準機能で圧縮,Firefox2でアップロード,fs_moodleで展開
3. WinXPでファイル・ディレクトリ作成,標準機能で圧縮,IE6でアップロード,fs_moodleで展開
4. WinXPでファイル・ディレクトリ作成,標準機能で圧縮,Firefox2でアップロード,fs_moodleで展開

の4パターンです.
また,それぞれのファイル・ディレクトリは

* 機種依存文字(丸囲みの数字やローマ数字)
* 半角カタカナ
* 問題のありそうな文字(現在絞り込み中)

といった文字をファイル名に含めました.
これら4パターンで展開したファイルを,Mac,WinXPのそれぞれのクライアントから表示した時にどういった動作をするのか試しました.

パターン1,パターン2について
MacでSafariから利用した場合は表示,ダウンロード,その後の解凍等に問題ありませんでした.
MacでFirefoxから利用した場合に,機種依存文字が”!”や”?”と表示されてしまいましたが,ダウンロード後のファイル名や解凍したファイル名は正常でした.
WinXPでIE6から利用した場合,表示に問題はありませんが,ダインロードしたファイルの機種依存文字が文字化けし,正常に解凍できませんでした.
WinXPでFirefoxから利用した場合,表示に問題はなく,ダウンロードしたファイルも正常ですが,解凍後のファイルが全て文字化けしました.
(解凍時の文字化け問題は,以前白井先生がご指摘されていたMoodle上で圧縮したファイルの文字化け問題と原因は同じだと思います.)

パターン3,パターン4について
まず,アップロード・fs_moodleで展開後のファイル名をサーバ上で確認した所,機種依存文字が”?”と置き換わって保存されてしまう問題がありました.
MacでSafariとFirefoxから利用した場合,上記問題以外は表示,ダウンロード,その後の解凍共に問題なく動作しました.
WinXPでIE6から利用した場合,問題のありそうな文字列が,正常に表示はされるものの,ダウンロードで文字化けしてしまう問題がありました.解凍は正常に行え,文字化けもありませんでした.
WinXPでFirefoxから利用した場合,表示,ダウンロード,その後の解凍等に問題ありませんでした.

ざっと確認した所,このような問題がありました.

これらを踏まえて,fs_moodleは私が作ってきた日本語ファイル名対応よりも優秀だと感じましたので,学内のMoodle利用者の方々にも試用していただこうと考えています.
現在Moodle1.8.3+ 07/10/24版をベースに開発中の学内のシステムをfs_moodle化しました.これを学内の方々に試用していただきフィードバックから,問題の原因究明や,他の問題が無いか検証したいと思います.
新たな問題や問題の解決策を見つけた場合はご報告させていただきます.

#ちなみにfs_converterのライセンスはGPLでしょうか.
Yuichi Saotome への返信

Re: moodle(特にWindowsサーバ)で日本語フォルダ/ファイル名を使用可能とする改造

- Tatsuya Shirai の投稿
ZIP関連はどこまで手を入れて良いのか,実に判断が難しいところです.

まずクライアント側で作成するZIPファイル書庫内のファイル名/フォルダ名ですが,
  • Macで作成(パターン1,2) :UTF-8
  • 日本語Windowsで作成(パターン3,4) :シフトJIS
が標準だと思います.Moodle上でUNZIPする際には,どのコードで作られていたとしても,
function zipitem2currentCharset($str)
{
$encoding = mb_detect_encoding($str, 'auto');
$str = mb_convert_encoding($str, 'UTF-8', $encoding);
return $str;
}
このコードで強制的にUTF-8(表面上の文字コードはUTF-8です)に変換しています.ファイルシステムに保存する際には,このUTF-8のファイル名を各ファイルシステムの文字コード(五月女さんのシステムではUTF-8ですので,UTF-8→UTF-8ですね)に変換します.これでうまくいくはずだったのですが...実はあちこちにcleanfilename()といった類の関数がチョコチョコと組み込まれていて,strtr()などのmb_string系ではない文字列操作関数をバンバンと使っています.先日もこの問題が悪さをしていることに気付いたので修正を施したばかりです(fs_moodle0.7f).

あ,ちなみにパターン1,2においてMacで作成してアップロードしたZIPファイルをWindowsXpでダウンロードしても正しく展開できない(ファイル名が化ける)のはPC上のZIP/UNZIPプログラムの仕様上の問題ですね.ヘッダーの文字コードの種別の違いをクライアントの展開ソフトウェアが吸収できないと無理です.

zip関係のソースコードにはあまり手を入れない方針で進めています.したがいまして,fs_moodle上でzip書庫を作成する際の文字コードはファイルシステムの文字コードです.サーバが日本語WindowsならばシフトJISで圧縮します.fs_moodleのファイルシステムの文字コードをシフトJIS以外(UTF-8など)に設定している場合,fs_moodleでZIP書庫作成の際に,シフトJISでZIP書庫作成,という選択肢が増えているはずです.そのままMoodle上でZIP書庫を作成すると日本語Windowsでは展開できませんが,ファイル名を強制的にシフトJISに変換することで,日本語Windows上で正常に展開できるようにする仕組みです.

でも,考えてみたら,これはクライアントが日本語WindowsのPCであることを前提としている仕組みですね.サーバが日本語Windowsの場合はUTF-8での書庫作成ができないということを意味しますので,ユーザにUTF-8か,シフトJISかを選べるようにするべきでした.

当方,Macの環境がありませんので,Macで作成したZIPファイルでのデバッグが行えません.実験に使用したZIPファイルをここにアップして頂けないでしょうか? それを用いてデバッグおよび機能の変更を行います.
(ただ,迂闊に手を入れすぎると,バックアップ/リストア機能に支障が出るので慎重に進めたいと思います)

fs_moodleは基本的にGPLです.と私が言ってしまって良いのか,自信がありません赤面.MoodleがGPLならばfs_moodleもGPLです.ソースコードに手を入れたところは全てオリジナルをコメントアウトして残してありますし,どこをどのように修正しているのか,は,Wikiに記録してあります.配布しているパッケージをfs_moodleと言うのも少しおかしいかな?と思いますし,fs_converter.phpとWikiのデータがfs_moodleなのでしょうねぇ.

奥村先生も仰っているように日本のMoodlerで行った日本語対応の知恵を集約するには実証するプラットフォームがいくつか必要であり,その一つがfs_moodleであると思っています.元々の動機が日本語Windows上でMoodleを使えるようにしよう,でしたが,プラットフォームに依存しない修正も多数,取り込まれてきました.

http://www.suzuka-ct.ac.jp/mech/moodle/mod/wiki/view.php?id=320&page=fs_moodle%E4%BF%AE%E6%AD%A3%E7%AE%87%E6%89%80%E4%B8%80%E8%A6%A7
このWikiがその資産なのですが,
  • 日本語WindowsなどのUTF-8に非対応なOSへの対応
  • IEが日本語URLに対してシフトJISしか未対応
  • 年月日や氏名の並びといったローカライズの軽微な改善
  • mb_string系関数を使用しないために発生する致命的な問題
が渾然一体となってしまっています.いつか時間ができたら,各修正箇所がどのレベルへの対応なのかを明記しようと思います(これはあまり大変な作業ではない).それと修正箇所のデータが逆引きになっていない点も補う必要がありますね.「ほにゃららの問題は,こことここを修正すれば改善できる」という情報です.

しかし...修正箇所が多くなり過ぎました.Moodle1.8からMoodle1.9に無事にアップグレード可能なのでしょうか.いまから戦々恐々です青あざ
Tatsuya Shirai への返信

Re: moodle(特にWindowsサーバ)で日本語フォルダ/ファイル名を使用可能とする改造

- Haruhiko Okumura の投稿
Mac OS X 10.5のファインダの機能で圧縮したものです。中身は「ほげ.txt」と「げほ.txt」です。ファイル名はUTF-8で入っています。

しかし,WindowsでアーカイブしたものでもStuffIt Expanderで今まで普通に展開できていましたので,ファイル名がShift JISでもちゃんと直してくれるようです。ということで,Shift JISにして束ねるということでWindowsもMacも大丈夫だと思います。

三重大学版Moodle(1.6ベース)でも最近のは課題の提出物全部とかフォーラムのディスカッションの添付ファイル全部とかをZipしてダウンロードする機能がついています(業者さんに作ってもらいました)。これも中身はShift JISファイル名です。
Haruhiko Okumura への返信

Re: moodle(特にWindowsサーバ)で日本語フォルダ/ファイル名を使用可能とする改造

- Tatsuya Shirai の投稿

ありがとうございます.

確かに,archive.zipを日本語Windows上で動作するアーカイブユーティリティのExpLzhを使用して展開したところ,正しく「ほげ.txt」と「げほ.txt」が得られました.

五月女さんの書き込みをもう一度,読み直してみると,ダウンロードしたzipファイルの中身が悪くて展開できなかった,のではなく,zipファイル自体のファイル名がWindowsXP+IE6では化けてしまったために展開できなかったと書いてありました.私の読み間違いです!

考えてみたら当然ですね.シフトJISでエンコードされたZIPファイルが広く世の中に蔓延している中,Macのアーカイバで展開できないとは思えません.逆はあり得ますが!(シフトJISに統一,は了解です).

そして...いつの間にか日本語ファイル名のファイルをIEでダウンロードすると文字化けする問題が復活していました.根本的な部分ですね.パッチを当てる作業をいつかの時点で失敗したのかも知れません.調査します.

Tatsuya Shirai への返信

Re: moodle(特にWindowsサーバ)で日本語フォルダ/ファイル名を使用可能とする改造

- Tatsuya Shirai の投稿

原因が分かりました.本家のMoodle1.8.3+のコードが改善されています.

つい先日のMoodle1.8.3+のCHANGESにそれらしい修正がありました.
差分を取ったときにも「おや?」と思ったのですが,そのまま忘れていました.
以前,水野さんが報告していた,IEでファイル名が化ける問題の対策,ヘッダーの$filenameをurlencode()すれば保存されるファイル名がマルチバイト環境下で化けない,という対策が本家に採用されたようです.
http://moodle.org/mod/forum/discuss.php?d=72567

lib/filelib.phpのfunction send_file()に,

// if user is using IE, urlencode the filename so that multibyte file name will show up correctly on popup
if (check_browser_version('MSIE')) {
$filename = urlencode($filename);
}
というコードが新しく追加されています.

当方の環境では,奥村先生が以前に示されたコードに基づいた以下のコードを用いていました(file.php).
$filename = $args[count($args)-1];
$ua = $_SERVER['HTTP_USER_AGENT'];
if (strstr($ua, "MSIE") && !strstr($ua, 'Opera')) {
$filename = mb_convert_encoding($filename, "CP932", "UTF-8");
// $filename = urlencode($filename); // 上記と置き換え可能
$filename = str_replace('#', '%23', $filename);
} else if (strstr($ua, "Safari")) {
$filename = "";
}
send_file($pathname, $filename, $lifetime, $CFG->filteruploadedfiles, false, $forcedownload);

つまりファイル名をシフトJISに変換した後に,urlencode()も行われていた,ということですね.
もし水野さんのurlencode()部分が有効だった場合は,urlencode()のurlencode()になってしまう,と.
file.phpでのIE対策のファイル名のコード変換の処理を行わないようにコメントアウトすると,いままでどおりにIEでも日本語ファイル名のファイルをダウンロードできるようになりました.
なお,urlencode()でファイル名を送信すると,半角空白が+(つまり”ほげ ほげ.zip"は"ほげ+ほげ.zip"になる)になってしまいます.

fs_moodleでは半角空白文字を含むファイル名をダウンロードできるように,ダブルクオートで括ってファイル名を送信しています.
if ($forcedownload) {
// @header('Content-Disposition: attachment; filename='.$filename);
@header('Content-Disposition: attachment; filename="'.$filename.'"');
} else {
// @header('Content-Disposition: inline; filename='.$filename);
@header('Content-Disposition: inline; filename="'.$filename.'"');
}
したがって,urlencode()の代わりにシフトJISで送信する方法でも良いのですが,どうしましょう.
filelib.phpのurlencode()をrawurlencode()に変更すれば,(当方の環境では)ファイル名中に半角空白を含んでも,+に変換されずに正しいファイル名で保存されます.
シフトJISに変換するのが良いのか,rawurlencode()が良いのか,判断し辛いですね.

なにはともあれ,上記file.phpの紫色の行のコードは不要になった,と考えて良いでしょう.
あとは新しく追加されたfilelib.php中のurlencode()をrawurlencode()にするか,mb_convert_encoding($filename, "CP932", "UTF-8")にするか,だけですね.

Tatsuya Shirai への返信

Re: moodle(特にWindowsサーバ)で日本語フォルダ/ファイル名を使用可能とする改造

- Haruhiko Okumura の投稿
いまうちのコードは

    $ua = $_SERVER['HTTP_USER_AGENT'];
    if (strstr($ua, "MSIE") && !strstr($ua, 'Opera')) {
      $filename = mb_convert_encoding($filename, "SJIS-WIN", "UTF-8");
      $filename = str_replace('#', '%23', $filename);
    } elseif (strstr($ua, "Safari")) {
      $filename = "";
    }

になっているみたいです。SJIS-WIN(CP932)にするのは日本の国内事情にしか合わないので,rawurlencodeすればどこの国でもうまくいくのであればそちらのほうがよさそうですね。ただ,長いパス名になってしまって途中で切れるという問題はなかったでしょうか。

Opera利用者はMSIEを詐称することが多いということを聞いたので if (strstr($ua, "MSIE") && !strstr($ua, 'Opera')) としたのですが,本家の修正ではそのあたりがなくなってしまっていますね。あと,ファイル名に # が含まれる場合の問題もありましたね。
Haruhiko Okumura への返信

Re: moodle(特にWindowsサーバ)で日本語フォルダ/ファイル名を使用可能とする改造

- Tatsuya Shirai の投稿
長いパス名の問題ですが,そうだ,試してみれば良いのだ,ということで試してみました.(OSはWindowsXP,fs_moodle0.7g)
”長い長いファイル名の長い長いファイル名の長い長いファイル名の長い長いファイル名の長い長いファイル名の.xls”(全角50文字+半角4文字)をダウンロードしてみました.テスト用の長い名前のファイルは,常識的な長さのファイル名のExcelファイルをアップロードし,Moodle上でリネームして作成しました.

$filename = rawurlencode($filename)の場合,ダウンロードされたファイルのファイル名は,「8Dの長い長いファイル名の長い長いファイル名の.xls」です.頭の8Dは%8Dの一部? 何はともあれ全角21文字+ゴミと拡張子(半角4文字)が限界のようです.

それに対して,$filename = mb_convert_encoding($filename, "CP932", "UTF-8")でシフトJISに変換した場合は,「長い長いファイル名の長い長いファイル名の長い長いファイル名の長い長いファイル名の長い長いファイル名の.xls」,正しく全角50文字+半角4文字で保存できました.

60文字もOKです.では100文字は?

Moodle上でのファイルのリネームには成功しました.
ダウンロードしたところ,さすがにここまでいくと無理があったようで,「ファイル名の長い長いファイル名の長い長いファイル名の長い長いファイル名の長い長いファイル名の長い長いファイル名の長い長いファイル名の長い長いファイル名の長い長いファイル名の長い長いファイル名の.xls」96文字+4文字,4文字ほど頭が欠けているようです.

ちなみに100文字+4文字のファイルは,アップロードに関しては問題ないようです.中途半端ですねぇ.

MS-DOS世代の私は半角8文字+拡張子3文字を潔しとして長らく生きてきたのですが,元・商社のデキるOLのうちの妻が作成する”名は体を十二分に表す”長い長いファイル名に思わず「ヤメテくれぇ青あざ」と言いかけたのですが,「もう制限に囚われる必要はないのだ」と思うと急に気が軽くなったのを良く覚えています.「なんでだめなの?」とキョトンとされて,ハタっと.

さすがに100文字は画面から溢れるので非常識ですが,rawurlencode()の20文字程度というのは短いですね.シフトJISにします.

ところでお恥ずかしい話ですが,#を%23に置換する理由は何でしたか?
いま試してみたところ,確かにシフトJISで送信する際に#は_に置換されていますので,%23に置き換える必要があることは確認しました.誰が#を_に置き換えているのかな?
添付 IE_MultibyteFilename.jpg
Tatsuya Shirai への返信

Re: moodle(特にWindowsサーバ)で日本語フォルダ/ファイル名を使用可能とする改造

- Haruhiko Okumura の投稿
#を置き換えたのは,確かうちで「ほげ#1.doc」が「ほげ.doc」になってしまうといった報告があったからだと思いましたが,ずいぶん前の話なので,Moodleが悪いのか何が悪いのか覚えていません。今はどこかで#を置き換えてくれているのでしょうか。
Haruhiko Okumura への返信

Re: moodle(特にWindowsサーバ)で日本語フォルダ/ファイル名を使用可能とする改造

- Haruhiko Okumura の投稿

あと,思い出したときに書いておきますが,うちでなぜCP932としないでSJIS-WINとしたかというと, PHP: Multibyte String Functions - Manual

Additional note: For the CP932 codemap, use SJIS-WIN instead.

と書いてあるんです。どういう意味だかわからないけれど,素直に従いました。

Haruhiko Okumura への返信

Re: moodle(特にWindowsサーバ)で日本語フォルダ/ファイル名を使用可能とする改造

- Tatsuya Shirai の投稿
了解です.
fs_moodleではCP932を多用していると思いますので,SJIS_WINに変更しておきます.
(CP932って何だろう?と思うのに対して,SJIS_WINは一目で分かるメリットもありますね)
Haruhiko Okumura への返信

Re: moodle(特にWindowsサーバ)で日本語フォルダ/ファイル名を使用可能とする改造

- Tatsuya Shirai の投稿
lib/filelib.phpのfunction send_file()の

// if user is using IE, urlencode the filename so that multibyte file name will show up correctly on popup
if (check_browser_version('MSIE')) {
$filename = urlencode($filename);
}
で用いられているcheck_browser_version()関数ですが,lib/moodlelib.php内で宣言されており,
case 'MSIE': /// Internet Explorer
if (strpos($agent, 'Opera')) { // Reject Opera
return false;
}
のように,Operaを弾いているようですので,大丈夫そうです.
他にも色々とテクニックが用いられているようですが,いまひとつ内容が理解できません.きっと何かノウハウなのでしょう...

Tatsuya Shirai への返信

Re: moodle(特にWindowsサーバ)で日本語フォルダ/ファイル名を使用可能とする改造

- Yuichi Saotome の投稿
五月女@信州大学です.

対応が遅くなりましたが,file.phpとlib/filelib.phpの該当箇所を変更したところ,
IE6にて文字化けすることなく,ファイルのダウンロードが出来る事を確認しました.
ありがとうございます.
MacOSXよりアップロードした,機種依存文字を含むファイル名でも正常にダウンロードできました.(丸囲み数字やローマ数字)

文字コードについては,文字コード変換よりはurlencodeに賛成なのですが,
urlencodeですとどうしても送信文が長くなり,POSTやGETの長さ制限に引っかかってしまうんですよね悲しい
何がベスト(もしくはベター)な解決策なのか悩んでしまいます.
Yuichi Saotome への返信

Re: moodle(特にWindowsサーバ)で日本語フォルダ/ファイル名を使用可能とする改造

- Haruhiko Okumura の投稿
ファイル名の長さを調べ,20文字?以下ならrawurlencodeし,そうでなければCP932に変換するとか?
Yuichi Saotome への返信

Re: moodle(特にWindowsサーバ)で日本語フォルダ/ファイル名を使用可能とする改造

- Tatsuya Shirai の投稿

そうですね.シフトJISに変換するという日本ローカルな対応はrawurlencode()した文字の長さによって,特例として入れるのが良いと思います.

その辺の調査と改善を行うのに併せて,もう一つ,実は気になっていることがあります.

まだ調査が中途半端な状態なのですが,send_file()関数はいま気にしている箇所(file.phpから呼ばれる箇所)以外にも,他の関数からも呼ばれているような気がします.マルチバイトへの対応として,urlencode()をsend_file()内に組み込んだ本家の改善は,この問題にも対応しようという現われなのではないでしょうか.

grepでsend_fileをコールしている箇所を調べたところ,$filenameを指定しないでsend_file()を呼んでいる箇所も多く,その場合は問題ないのかも知れませんが,いくつか$filenameを引数として渡している箇所もあるようです.だとすると,これらのIE対応は本家同様にsend_file()内に組み込むべきなのか,とも思います.

file.phpから呼ばれる箇所以外は,ANK文字列のファイル名以外はあり得ない,という性質を持つならば現状で構わないと思うので,いったい,どのようなファイル名を渡される可能性があるのかを見極めながら対応策を考えています.

#気にしすぎ? send_file()内に移動させてしまいましょうか.

Tatsuya Shirai への返信

Re: moodle(特にWindowsサーバ)で日本語フォルダ/ファイル名を使用可能とする改造

- Haruhiko Okumura の投稿
なるほど,そうですね。

ではsend_file内に移動しましょう。

Windowsのパス名の限度って何でしたっけ。UTF-8をrawurlencodeすると,UTF-8のため日本語なら1文字3バイトで,それがrawurlencodeでさらに3倍されて,文字数の9倍のバイト数になる可能性があるんですよね。
Haruhiko Okumura への返信

Re: moodle(特にWindowsサーバ)で日本語フォルダ/ファイル名を使用可能とする改造

- Yuichi Saotome の投稿
たしかに,CP932への変換は日本独自の対応になりそうですから,ファイル名の長さによって特例対応するのが良いのでしょうね.
また,send_file()内を変更するのは良い案だと思います.

WindowsXPのフルパスは意外と短かった気がしてググった所,
ファイルシステムによるみたいですが,255バイトのようです.
http://q.hatena.ne.jp/1169126961
Yuichi Saotome への返信

Re: moodle(特にWindowsサーバ)で日本語フォルダ/ファイル名を使用可能とする改造

- Tatsuya Shirai の投稿
一応,実験完了です.
Moodle1.8.3+用の改造です.

file.php中の
$ua = $_SERVER['HTTP_USER_AGENT'];
if (strstr($ua, "MSIE") && !strstr($ua, 'Opera')) {
$filename = mb_convert_encoding($filename, "SJIS-WIN", "UTF-8");
$filename = str_replace('#', '%23', $filename);
} elseif (strstr($ua, "Safari")) {
$filename = "";
}
のようなIE対応のコードを削除します.これらをlib/filelib.php中にsend_file()に移動します.

lib/filelib.php, send_file(): 347行近辺.最新のMoodle1.8.3+では,以下のようなコードが追加されています.
// if user is using IE, urlencode the filename so that multibyte file name will show up correctly on popup
if (check_browser_version('MSIE')) {
$filename = urlencode($filename);
}

この箇所を以下のように修正しました.
// if user is using IE, urlencode the filename so that multibyte file name will show up correctly on popup
if (check_browser_version('MSIE')) {
// $filename = urlencode($filename);
if (strlen(rawurlencode($filename)) > 21 * 3 * 3) {
$filename = mb_convert_encoding($filename, "SJIS-WIN", "UTF-8");
$filename = str_replace('#', '%23', $filename);
} else {
$filename = rawurlencode($filename);
}
} else if (check_browser_version('Safari')) {
$filename = "";
}

check_browser_version()関数をオリジナル通りに利用してみました.
21文字×3でUTF-8,さらに×3はURLエンコード分です.取り敢えず色々と実験してみましたが,大体この程度で良さそうです.
urlencode()ではなく,rawurlencode()を使用しているのは,ファイル名に半角空白を含む場合です.
オリジナルのMoodleではファイル名に半角空白を許していないので,urlencode()でも問題ありませんが,当方の環境では半角空白も許しているのでrawurlencode()を使用しました.関数としての機能の違いは半角空白を+に変換するか%20(でしたっけ?)に変換するのかの違いだけだと思いますので,rawurlencode()でも皆さんの環境で問題は無いと思います.

send_file()関数の頭のところで,
$mimetype = ($forcedownload and !$isFF) ? 'application/x-forcedownload' :
($mimetype ? $mimetype : mimeinfo('type', $filename));
のように$filenameを利用している箇所があります.この処理の前にコード変換をした方が良いのか,しない方が良いのか,少しだけ悩みました.
実験した感じでは,どちらでもあまり挙動に違いがありませんでしたので,オリジナルに近い改造を選択しました.

近日中に,fs_moodleのパッケージも更新します.(今週末?)

Tatsuya Shirai への返信

Re: moodle(特にWindowsサーバ)で日本語フォルダ/ファイル名を使用可能とする改造

- Tatsuya Shirai の投稿

 send_file()内に移動させたファイル名のエンコードをブラウザの種別に合せて変換する機能を関数にしてみてはどうかと考えて,いまテストしています.

// ブラウザに合わせてダウンロードファイル名のフォーマットを変更する
function convert_download_filename_encoding($filename) {
    if (check_browser_version('MSIE')) {
        if (strlen(rawurlencode($filename)) > 21 * 3 * 3) {
            $filename = mb_convert_encoding($filename, "SJIS-WIN", "UTF-8");
            $filename = str_replace('#', '%23', $filename);
        } else {
            $filename = rawurlencode($filename);
        }
    } else if (check_browser_version('Safari')) {
        $filename = "";
    }
    return $filename;
}

send_file()以外にも何箇所か(具体的にはWikiのエクスポート機能)で,ダウンロードしたファイル名がIEだと文字化けする箇所があります.メンテナンスもやり易い気がします.

 さて,ところで.ブラウザがSafariの場合は$filename = ""としていますが,これはこれで良いのでしょうか??? 実は前々から少し気になっていました.send_file()で,$pathが指定されている場合は大丈夫,ということだと,上記関数をあちらこちらで使用するのに問題があります.

 そもそも(Wikiのエクスポートのように)send_file()を使わないのがおかしい,となれば,そのように考えますが,もしSafariの場合も$filename=""にしなくても問題が無いのならば安心です(つまりFirefox同様に生のUTF-8をHeaderに渡して構わない).

Tatsuya Shirai への返信

Re: moodle(特にWindowsサーバ)で日本語フォルダ/ファイル名を使用可能とする改造

- Tatsuya Shirai の投稿

 奥村先生のWebページに理由が書いてありました.

http://oku.edu.mie-u.ac.jp/~okumura/php/filename.php

なるほど.Safariにもこのような悩みがあったのですね.

 関数としては,Safariの場合は空文字を返すということとし,関数を利用した側でもし戻り値が空文字ではいけない(画面表示などに再利用する,というのもSJIS-WINやrawurlencode()された文字を返す可能性のある関数の性質上,変ですが)場合は自分で判断しなさい,とコメントを付しましょう,か.