Это чуть не выбило меня из головы, и, пытаясь найти простой способ обойти ожидания API форм, я столкнулся с этим вопросом. Ответ Клайва был началом того, как я понял это, потому что похоже, что вы можете предоставить источник в качестве первого аргумента для file_save_upload (), но, как оказалось, вы не можете. По крайней мере, в текущем друпале 7.30.
Я проверил предоставленную им ссылку и разобрал функцию. По сути, даже если вы передаете полный путь к исходному коду, он все равно ищет первый аргумент в массиве $ _FILES по пути вниз. Кто знает почему, но что за глупая идея. Итак, я сделал это:
//after verifying all post fields are set...
$node = new stdClass();
$node->type = 'user_files';
node_object_prepare($node);
$node->title = $_POST['title'];
$node->author = 2; //hardcoded because only admin uses this form
$node->uid = 2;
$node->language = LANGUAGE_NONE;
$node->body[$node->language][0]['value'] = $_POST['body'];
$node->body[$node->language][0]['summary'] = text_summary($_POST['body']);
$node->body[$node->language][0]['format'] = 'filtered_html';
$node->field_first_name[$node->language][0]['value'] = $_POST['first_name'];
$node->field_last_name[$node->language][0]['value'] = $_POST['last_name'];
node_save($node);
if(isset($_FILES['file']['tmp_name']) && $_FILES['file']['name'] != '')
{
//upload file
$file = new stdClass();
$file->uid = 2;
$file->status = 0;
$file->filename = trim(drupal_basename($_FILES['file']['name']), '.');
$file->uri = $_FILES['file']['name'];
$file->filemime = file_get_mimetype($file->filename);
$file->filesize = $_FILES['file']['size'];
$file->filename = file_munge_filename($file->filename, 'jpg jpeg gif png doc docx pdf');
$file->destination = file_destination('private://' . $file->filename, FILE_EXISTS_RENAME);
$file->uri = $file->destination;
if (!drupal_move_uploaded_file($_FILES['file']['tmp_name'], $file->uri)) {
return false; //set errors or do whatever you want on error
}
else
{
drupal_chmod($file->uri);
$existing_files = file_load_multiple(array(), array('uri' => $file->uri));
if (count($existing_files)) {
$existing = reset($existing_files);
$file->fid = $existing->fid;
}
if ($file = file_save($file)) {
// Add file to the cache.
$node->field_file[$node->language][0]['uri'] = 'private://'.$file->filename;
$node->field_file[$node->language][0]['fid'] = $file->fid;
$node->field_file[$node->language][0]['display'] = 1;
$node->field_file[$node->language][0]['description'] = 'User uploaded file';
node_save($node);
//do we notify someone?
}
}
}
То, что это делает, создает узел указанного типа. В этом случае user_files, затем, если файл загружен, добавьте файл в таблицу мультимедиа или в таблицу файлов, или как она там называется. Затем добавляет ассоциацию к вновь созданному узлу.
Это уродливо? Да уж. Почему я не использовал внутренний API формы drupal? Заткнись, вот почему. У нас не всегда есть выбор, поэтому, когда клиент запрашивает базовую форму, которая просто отправляет его по электронной почте, легко и быстро создать простое поле, которое отправляет через почтовый API-интерфейс шимпанзе или что-то в этом роде. Потом позже они добавляют, что хотят файлы. Позже они хотят, чтобы это добавилось к серверной части drupal, и внезапно у вас появился снежный ком ужаса, который был бы намного проще, если бы это было сделано с помощью API формы для начала. Я не знаю, кто начал это, но я должен был закончить это, и я сделал это с этим ужасным взломом. Надеюсь, это поможет вам или тому, кто еще вращается в друпальном вихре ужаса.