* 添付ファイルのリネーム時、バックアップファイルとログファイルがリネームがされない [#b957ec2d] - ページ: [[BugTrack2]] - 投稿者: [[umorigu]] - 優先順位: 普通 - 状態: 完了 - カテゴリー: プラグイン - 投稿日: 2011-05-08 (日) 13:07:06 - バージョン: 1.4.7 - リリース予定バージョン: 1.5.1 ** メッセージ [#lb2735d6] *** 内容 [#debc14c0] attachプラグインで添付ファイルのリネームができますが、物理ファイルのリネームは最新の1ファイルのみにしか行われておらず、過去に削除されたバックアップファイル(拡張子 .1, .2, ...)とステータスファイル(拡張子 .log)のリネームが行われていません。 結果として、バックアップファイルが失われる、ダウンロードカウンタがリセットされる、などの不具合が発生します。 *** 条件 [#w2850e7c] - バックアップファイルの場合: -- PLUGIN_ATTACH_DELETE_ADMIN_NOBACKUP が FALSE で、添付ファイル削除時にバックアップが残るケースにて - ステータスファイルの場合: -- 常に *** 対策 [#u898ff59] diff --git a/attach.inc.php b/attach.inc.php --- a/attach.inc.php +++ b/attach.inc.php @@ -672,10 +672,40 @@ if (file_exists($newbase)) { return array('msg'=>$_attach_messages['err_exists']); } - if (! PLUGIN_ATTACH_RENAME_ENABLE || ! rename($this->basename, $newbase)) { + if (! PLUGIN_ATTACH_RENAME_ENABLE) { return array('msg'=>$_attach_messages['err_rename']); + } else { + if (! rename($this->basename, $newbase)) { + return array('msg'=>$_attach_messages['err_rename']); + } + // リネーム成功 + // バックアップファイル・ログファイルもリネームする + // エラー処理は省略 + $rename_targets = array(); + if ($dir = opendir(UPLOAD_DIR)) { + $matches_leaf = array(); + if (preg_match('/(((?:[0-9A-F]{2})+)_((?:[0-9A-F]{2})+))$/', $this->basename, $matches_leaf)) { + $attachfile_leafname = $matches_leaf[1]; + $attachfile_leafname_pattern = preg_quote($attachfile_leafname, '/'); + $pattern = "/^({$attachfile_leafname_pattern})(\.((\d+)|(log)))$/"; + + $matches = array(); + while ($file = readdir($dir)) { + if (! preg_match($pattern, $file, $matches)) + continue; + $basename2 = $matches[0]; + $newbase2 = $newbase . $matches[2]; + $rename_targets[$basename2] = $newbase2; + } + } + closedir($dir); + } + foreach ($rename_targets as $basename2=>$newbase2) { + $basename2path = UPLOAD_DIR . $basename2; + echo "rename '$basename2path' to '$newbase2'<br>\n"; + rename($basename2path, $newbase2); + } } - return array('msg'=>$_attach_messages['msg_renamed']); } ** 例 [#kab22c4c] バックアップファイルを持つ a.txt を b.txt にリネームしたとき: rename 'attach/41_612E747874.1' to 'attach/41_622E747874.1' rename 'attach/41_612E747874.log' to 'attach/41_622E747874.log' ** 対応 [#q3766723] ** 実装 [#q3766723] - [[commit:024002757aa74f857fe68e53b38405bd85b08828]] -------- * コメント [#j526c416] - 関連: -- [[BugTrack2/170]] -- &new{2011-05-07 (土) 23:31:20}; -- [[PukiWiki/1.4/ちょっと便利に/attachプラグインでのリネームのバックアップファイル対応]] -- &new{2011-05-08 (日) 23:05:05}; - エラー処理・・・? -- [[henoheno]] &new{2011-05-08 (日) 23:06:17}; - echo "rename '$basename2path' to '$newbase2'<br>\n";とリネームログ?を直に出力してるから、スキン→(pkwk_common_headers()→pkwk_headers_sent())→PHPのheaders already sentエラーって意味ではないよなたぶん。 if (! rename($this->basename, $newbase)) { return array('msg'=>$_attach_messages['err_rename']); } のようなエラーメッセージ処理を入れていないという意味かなとエスパーしてみる -- &new{2011-05-09 (月) 03:40:39}; - ↑そういう意味です。(rename の失敗を無視している).ここはエラーになっても処理続行が望ましいと思いました。一番重要なrenameが成功した後なので -- [[umorigu]] &new{2011-05-09 (月) 22:37:24}; - (5年前の自分に対してですが)添付ファイルがリネームされたときに過去に削除された同名ファイルをリネームするのは一般的には正しくありませんね。statusファイル(.log)がリネームされないのはバグですので修正します -- [[umorigu]] &new{2016-01-26 (火) 02:48:43}; - (当時、EUC_JP→UTF-8移行を行っていて添付ファイル名を短くしたかったので問題をとり違えました) -- [[umorigu]] &new{2016-01-26 (火) 03:01:07}; - ↑と、書きましたが調査したところ、現状では同名の添付ファイルは.logファイルを共有するなど、まとめて扱うような設計になっています。今のタイミングで大幅な構造変更はしたくないので、リネームの際も追従してしまうことは仕様(現状の制約)として扱いたいと思います -- [[umorigu]] &new{2016-01-27 (水) 00:38:37}; - 修正しました -- [[umorigu]] &new{2016-01-27 (水) 01:00:01}; #comment