HTMLエディタから呼び出すファイルブラウザでのリネームが正常に動作しない原因

HTMLエディタから呼び出すファイルブラウザでのリネームが正常に動作しない原因

- Tatsuya Shirai の投稿
返信数: 7
前々から気になっていたのですが,添付した図のように,HTMLエディタの「リンクの挿入」から「閲覧」を選び,サイト上のファイルへのリンクを選択する画面(ファイルブラウザ)で,ファイルやフォルダの削除,移動,ZIP(+リスト,展開),リネーム,フォルダの作成,ファイルのアップロードを行うことができるファイラー画面が開きます.
この画面でファイル名の左側のチェックボックスをチェックし,「リネーム」を選んでも添付した図の左下図のように「を下記の名前にリネーム」と,オリジナルのファイル名が表示されませんでした.もちろん,リネームもできませんでした.
この原因はどうやら,lib/editor/htmlarea/coursefiles.phpの123行目,
function set_rename(strfile) {
var upper = window.parent.document;
// upper.getElementById('irename').value = strfile;
upper.getElementById('irename').file.value = strfile;
return true;
}

この.file.が抜けているのが原因だと思います.皆さんの環境では如何でしょうか?


チェックボックスをOnにすると,そのファイル名をJavascriptのset_rename()を呼んで親のフォームの,
<td><form id="irename" method="post" action="/mech/moodle/lib/editor/htmlarea/coursefiles.php" target="fbrowser">
<input type="hidden" name="id" value="13" />
<input type="hidden" name="wdir" value="" />
<input type="hidden" name="file" value="" />
<input type="hidden" name="action" value="rename" />
<input type="hidden" name="sesskey" value="rhYaacFFrF" />
<input name="btnRename" type="submit" id="btnRename" value="リネーム" /></form></td>
このfileの値を書き換えているようです.ところが現状のset_rename()ではfileのvalueを書き換えていない.その結果,actionであるlib/editor/htmlarea/coursefiles.phpの引数としてfile=で渡されるべきファイル名が空白のままであることで,
echo " <input type=\"hidden\" name=\"oldname\" value=\"$file\" />\n";
このoldnameの値も空白.その結果,実際にリネームする際にオリジナルのファイル名が空白のまま処理に入ってしまうようです.処理が三段階になっているため追い掛けるのが億劫で,いままで無視していましたウインク

とりあえず上記の修正(赤い箇所)を行うことでIEでも,添付した図の右下図のようにフォルダとファイル名を正しくリネームできることを確認しました.

添付 rename.jpg
Tatsuya Shirai への返信

Re: HTMLエディタから呼び出すファイルブラウザでのリネームが正常に動作しない原因

- Tatsuya Shirai の投稿
> とりあえず上記の修正(赤い箇所)を行うことでIEでも,添付した図の右下図のようにフォルダとファイル名を正しくリネームできることを確認しました.

先の書き込みで,”IEでも”と書きましたが,本件はFirefoxでも発生していた問題です.ついつい”Firefoxなら当然としてIEであっても大丈夫”という気持ちが出た次第です.


Tatsuya Shirai への返信

Re: HTMLエディタから呼び出すファイルブラウザでのリネームが正常に動作しない原因

- Haruhiko Okumura の投稿
うちで使っているMoodle 1.6.xでは

        function set_rename(strfile) {
            if(window.parent.document.irename != null) {
                window.parent.document.irename.file.value = strfile;
            }
            return true;
        }

となっており,こちらはたぶん正しいのでしょうね。
Haruhiko Okumura への返信

Re: HTMLエディタから呼び出すファイルブラウザでのリネームが正常に動作しない原因

- Tatsuya Shirai の投稿
そうですね.正しいと思います.
Moodle1.7かMoodle1.8になる際に消してしまった,というのも変な話ですね.何か他に理由があって行った修正なのでしょうか...?

Tatsuya Shirai への返信

Re: HTMLエディタから呼び出すファイルブラウザでのリネームが正常に動作しない原因

- Haruhiko Okumura の投稿
単に書き方を変更したときの編集ミスのような気もしますね。
本家のバグトラッキングシステムに書き込んでみてはどうでしょうか。
Haruhiko Okumura への返信

Re: HTMLエディタから呼び出すファイルブラウザでのリネームが正常に動作しない原因

- Tatsuya Shirai の投稿
はい,発見と同時にBugTrackerに報告済みですウインク

でも,いままでに報告した件(5件くらい?),まだ一つも対策をして頂いていません.全ての問題点は対策も込みで報告しているのですが...重要度の低い問題ばかり見付けているのでしょうか.(英語力が無いせいだという指摘もある恥ずかしい


ダウンロード可能なアーカイブを調べたところ,

OK: 1.6.5
OK: 1.7.2
OK: 1.7.2+

NG: 1.8.2
NG: 1.8.2+
NG: 1.9

です.1.8にバージョンアップした頃に変更されているようですね.手元の古いバージョンを調べてみたところ,
2007年3月30日にダウンロードした2006101011(1.7.1+)ではOKですが,
2007年4月 5日にダウンロードした2007021502(1.8+)ではfileが省かれています.

CHANGESには8月以降の分しか記録がありませんので,意図的にfileを取り除いたのかどうかは分かりません.

htmlareaのバージョンを上げた際にMoodle固有の修正を施すときに修正し忘れたのかな?と思ったのですが,バージョン自体はrelease-note.htmlを見る限り,1.7.1+も1.8+も3.0beta release(This release was compiled on Aug 11, 2003 [21:30] GMT.)で同一です.ただ,ファイルのタイムスタンプは1.7.1+のcoursefiles.phpが2006/9/14(30,054byte)であるのに対して,1.8+のcourserifles.phpは2007/01/28(33,559byte)ですので更新されているようです.


どこが違うのかをもう少し詳しく調べてみたところ,やはり奥村先生の仰るように,単に書き換える際のミスのようですね.以下に示すように,1.8からは,getElementById()を使用するように改変されています.その際に,単にfileを忘れちゃったのでしょう.

***** coursefiles.php.1.7.1
function set_rename(strfile) {
if(window.parent.document.irename != null) {
window.parent.document.irename.file.value = strfile;
}
return true;
***** COURSEFILES.PHP.1.8
function set_rename(strfile) {
var upper = window.parent.document;
upper.getElementById('irename').value = strfile;
return true;
*****

ただ,差分をとって調べているときに,もう一箇所,getElementById()への書き換えでfileの消えている箇所がありました.これがどのような影響を与えるのかは,未調査です.

***** coursefiles.php.1.7.1
var ren = upper.getElementById('irename');
if(ren != null) {
upper.irename.file.value = "";
}
var prev = window.parent.ipreview;
***** COURSEFILES.PHP.1.8
upper.getElementById('irename').value = 'xx';

var prev = window.parent.ipreview;
*****

Tatsuya Shirai への返信

Re: HTMLエディタから呼び出すファイルブラウザでのリネームが正常に動作しない原因

- Tatsuya Shirai の投稿
lib/editor/htmlarea/coursefiles.phpの
新しく発見した file抜けの問題箇所ですが,抜き出しますと,

(Moodle 1.7.2)
function reset_value() {
(中略)
var ren = upper.getElementById('irename');
if(ren != null) {
upper.irename.file.value = "";
}

(Moodle 1.8.2+)
function reset_value() {
var upper = window.parent.document;
(中略)
upper.getElementById('irename').value = 'xx';

やはり1.8にバージョンアップする際に,getElementById()を使用するように書き換えた際にfileを入れ忘れているようです.このreset_value()は主にファイルブラウザで一つう上のフォルダに戻るボタンを押す際のonclickとして割り当てられています.未確認ですが,感触としてはリネームをキャンセルした場合も呼ばれているような気がします.Formの値をリセットしています.その一部としてファイル/フォルダ名左側のチェックボックスをチェックした際のリネームするファイル/フォルダ名の情報もクリアしているようです.一つ上のフォルダに移動したらこのファイルの情報は無駄ですからね.

さて,Moodle1.8.2+では,単にクリアするのではなく,'xx'という値を入れるように改変されていますが...特別な機能は無さそうです.空っぽだと何か好ましくないのだろう?とも思ったのですが...分かりません.

reset_value()の働きをリネームと関連付けて説明します.
  • ファイル名(例えばここではfoo.txtとします)の左側のチェックボックスをチェックすると,set_rename()によりファイル名(パスは含まれない.foo.txtのみ)がフォームのfile="foot.txt"と格納される.
  • リネームボタンを押すと確認画面が表示されます.新しいファイル名を入力してリネームを押せばリネームされますが,キャンセルを押せばリネームされずにファイルブラウザに戻ります.この際にreset_value()が呼ばれていると思いますが,オリジナルのソースではfileのvalueを書き換えませんので,file="foo.txt"のままです.
  • キャンセルしてファイルブラウザに戻ったとき,ファイルのリストの中のどのチェックボックスもチェックされていません.しかし,リネームボタンを押すと先ほど選択したファイルの情報がirename.file="foo.txt"と残っていますので,「foo.txtを下記のファイル名にリネーム」と表示されてしまいます.これはまだ問題としては軽微なほうです.
  • 一つ上のフォルダに移動します.この際にreset_value()が呼ばれるのですが,irename.file=foo.txtが残っていますので,リネームボタンを押すと,このフォルダにはfoo.txtが存在しないにも関わらず「foo.txtを下記のファイル名にリネーム」と表示されてしまいます.もし新しいファイル名を入力してリネームを押すとエラーが発生するでしょう.
upper.getElementById('irename').value = 'xx';

upper.getElementById('irename').file.value = 'xx';
と書き換えれば,リネームをキャンセルした後も,一つ上のフォルダに移動した後も,リネームを押すと「xxを下記のファイル名にリネーム」と表示されます.もしかしたらxxは特別な名前なのか?と思って試しにxxを別の名前にリネームしてみたのですが,エラーでした.

それならいっそ,単に,
upper.getElementById('irename').file.value = '';
のように値を空にして,リネームの確認画面でfileが空の場合はリネームさせないようにするのが筋では無いでしょうか.

Tatsuya Shirai への返信

Re: HTMLエディタから呼び出すファイルブラウザでのリネームが正常に動作しない原因

- Tatsuya Shirai の投稿
lib/editor/htmlarea/coursefiles.phpのfunction html_header(),142行近辺を
// upper.getElementById('irename').value = 'xx';
upper.getElementById('irename').file.value = '';
このように書き換えた上で,
329行目近辺(switch($action)の'rename'の中)に,以下のように$fileが空の場合は何もしない(ディレクトリのリストを再表示してbreakする)ようにすることで,誤ってリネームを押した際の問題(小さな問題ですが...)は改善できます.実際にこの点が問題になることはかなり少ないと思いますが,気持ちはスッキリとします.

} else {
if (empty($file)) {
html_header($course, $wdir);
displaydir($wdir);
html_footer();
break;
}
$strrename = get_string("rename");
$strcancel = get_string("cancel");
$strrenamefileto = get_string("renamefileto", "moodle", $file);
html_header($course, $wdir, "form.name");

(赤いブロックを追加します)