フォームAPIファイルのアップロード


9

フォームに次のコードがあります。

$form['new']['upload'] = array(
  '#type' => 'file',
  '#title' => t(''),
  '#size' => 40,
);

送信ハンドラでは、ファイル名を返しますが、ファイルを保存せず、ファイルオブジェクトを返します。他に何をする必要がありますか?

私がやろうとしていることは、ノードのファイルフィールドに保存されているファイルをアップロードできるブロックを作成することです。

回答:


8

file_save_upload()とそれを呼び出す関数を見てください

関数はファイルの検証を処理し、新しい場所に保存します。Drupal 7では、これによりファイルがfile_managedテーブルに追加されます。
ファイルは一時ファイルとして保存されるため、後でファイルのステータスを永続的に設定してください。

おそらく、フォームの検証フック内(送信ハンドラの前)にfile_save_upload関数を実装することで、ファイルのアップロードが失敗した場合や、検証要件を満たしていない場合にユーザーに警告できます。

検証しようとしている画像フィールドの名前がの場合、imagefile_save_uploadの最初のパラメータは次のように画像にする必要があります。

$ path = file_save_upload( 'image'、...);

この関数は、画像がアップロードされたサーバー上のパスを返します(たとえば、そのパスをカスタムデータベースフィールドに保存できます)。


4

フォーム定義にこれがありません:

   $form['#attributes']['enctype'] = 'multipart/form-data'; // If this is not here, upload will fail on submit

これが、フォームにファイルアップロードウィジェットを作成するために使用するロジックです。

   // these give us the file upload widget: 
   $form['#attributes']['enctype'] = 'multipart/form-data'; // If this is not here, upload will fail on submit
   $form['fid'] = array( '#title'        => t('Upload image'),
                         '#type'         => 'file',
                         '#description'  => t('Images must be one of jpg, bmp, gif or png formats.'),
                       ); 

ロジックに画像のファイル名の制限があるため、フォームの検証コールバックにあるそのロジックに対応するものを次に示しますが、必要に応じてこれを送信コールバックに配置できます。

   // @see: http://api.drupal.org/api/function/file_save_upload/6
   // $file will become 0 if the upload doesn't exist, or an object describing the uploaded file
   $file = file_save_upload( 'fid' );
   error_log( 'file is "'.print_r( $file, true ).'"' );
   if (!$file) {
      form_set_error('fid', t('Unable to access file or file is missing.'));
   }

それでおしまい。


3
$form['#attributes']['enctype']Drupal 7では実際には必要ありません。自動的に処理されます
user724228

3
multipart/form-datadrupal 7には必要ありません。ファイルフィールドを使用する場合、drupal 7でビルドされます。
FLY

@bsenftner私はあなたと同じ方法を使用していますが、試してみるとそれがわかります(つまり$file === nullno file was uploaded仕様に従って:api.drupal.org/api/drupal/includes!file.inc/function /…)その場合、どうすればよいですか?このようなことをデバッグするにはどうすればよいですか?
Shawn

@ショーン:あなたはDrupal 7で働いていますか?このロジックはDrupal 6でテストされています。まだD7で試す機会がなかったので、D7を使用している場合は「わかりません」と答えます。D6を使用している場合は、正常に機能しているはずです。「fid」がファイルアップロードウィジェットのフィールド名であることを確認してください。
Blake Senftner、2012年

どちらの質問にも当てはまります。私はウィジェットの正しい名前を持っていると確信しており、D7を使用しています。私はこれを新しい質問にすべきだと思います...
Shawn

3

画像のアップロードをサポートする必要があるテーマで主に使用する一般的な検証関数があります。あなたはそれをそのまま、または小さな変更で使用できるかもしれませんが、これはあなたを遠くに連れて行くはずです。

/**
 * Validate/submit handler used for handling image uploads
 */
function module_upload_image_validate($form, &$form_state) {
  // This is not needed, I use this to use the same validate function
  // for several fields.
  $key = $form['#key'];
  $file = file_save_upload($key, array(
    'file_validate_is_image' => array(),
    'file_validate_extensions' => array('png gif jpg jpeg'),
  ));
  if ($file) {
    // Get the image info to get the correct extension for the uploaded file.
    $info = image_get_info($file->filepath);
    if (file_move($file, 'destination/filename'. $info['extension'], FILE_EXISTS_REPLACE)) {
      // Mark the file for permanent storage.
      file_set_status($file, FILE_STATUS_PERMANENT);
      // Update the files table.
      drupal_write_record('files', $file, 'fid');
      $form_state['values'][$key] = $file->filepath;
    }
    else {
      form_set_error($key, t('Failed to write the uploaded file to the site’s files folder.'));
    }
  }
}

この関数を使用して、フォーム送信ハンドラーの値としてファイルパスを取得します。使用方法によっては、代わりにファイルIDが必要になる場合があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.