web-dev-qa-db-ja.com

アップロード時にファイル名を変更する

アップロードされたファイル名にプレフィックスを自動的に追加して、後で無害なスクリプトで処理できるようにしています。ノードの作成/編集中にユーザーがファイルをアップロードしているときにそれを実行したいと思います。

そのために、私はhook_file_validate($field)を使用しています。ここで、ファイルが正しいかどうかを確認してから、$field->destinationを使用して、新しいファイル名を定義します。

驚いたことに、私の問題は、適切なファイル名(ノードのnid、親グループのnid、または他のフィールドの情報)を生成するコンテキストを取得することにあります。ファイルをアップロードすると、ウェブサイトの一部のみがJavaScriptによってリロードされ、hook_file_validateの前にhook_form_alterがトリガーされます。それがトリガーされたとき、私はどこにいるのかを教えてくれるデータにアクセスできません。

これまでのところ、私は試しました:

$_REQUEST['destination']

フォーム全体が読み込まれたときに(タイプミスではなく)定義されているが、フォームのファイルフィールドが再読み込みされたときは未定義

$_GET['nid']

再び-未定義

arg(0); arg(1); arg(2);

file ajax field_quest_fileを返しますが、あまり役に立ちません

uidにアクセスできますが、一意のファイル名を作成するだけでは不十分です。

3
Pawel G

私のコメントに続いて、次のような追加の送信ハンドラでこれを行うことを提案します:

新しい送信ハンドラを追加します。

function misc_form_alter(&$form, &$form_state, $form_id) {
  if($form_id == 'YOUR_CONTENT_TYPE_node_form') {
    $form['actions']['submit']['#submit'][] = 'rename_files';
  }
}

そして、新しい送信ハンドラで:

function rename_files($form, &$form_state) {

  $node = $form_state['node'];

  global $user;

  // Loop over the uploaded files. Be sure to re-name field_files to the name of 
  // your file field.
  foreach($node->field_files[LANGUAGE_NONE] as $item) {

    // Load the file object
    $file = file_load($item['fid']);

    // To set the destination first remove the filename from the stream wrapper 
    // URI.
    $destination = str_replace($file->filename, '', $file->uri);

    // Modify this line to the name of your group field.
    $group = $node->field_group[LANGUAGE_NONE][0]['value'];

    // And then append the group, uid and put the filename back on the end.
    $destination .= $group.$user->uid.$file->filename;

    // And finally rename the file.
    file_move($file, $destination);
  }

}
4
Felix Eve

ファイルの名前を変更する代わりに、別の方法を使用して、宛先フォルダーを変更しました。

私は、POST/GET引数とフォームの他のフィールドの値への完全なアクセス権があるhook_form_alterのレベルからそれを行います。

function myModule_form_alter(&$form,&$form_state,$form_id){
    switch($form_id){
        case 'nodetype_node_form':
            //prepare whatever prefix you want
            //in my case gid/uid/
            $dest_folder = _make_destination_folder($form);
            //findout which file will be added next
            //the form is rebuild each time a file is uploaded
            $delta = form['field_files'][LANGUAGE_NONE]['#file_upload_delta'];
            //instead of renaming files just change the destination folder
            form['field_files'][LANGUAGE_NONE][$delta]['#upload_location'] = 'private://'.$dest_folder;
            break;
    }
}

このようにして、ファイルはノードが保存される前に、ランダムで予測できない一意の場所に配置されます。このアプローチのボーナスは、グループとユーザーに基づいてファイルをフォルダーに分類することです

1
Pawel G