Программно вставить файл в файловую систему Drupal? - PullRequest
2 голосов
/ 16 января 2012

Я беру файл с помощью CURL и хочу сохранить его локально, но он подключается к файловой системе Drupal.Должен ли я сделать ручную вставку или есть лучший способ?Самое близкое, что я мог найти, было:

function image_field_insert($entity_type, $entity, $field, $instance, $langcode, &$items);

Но я не знаю, как это использовать.Есть лучшие предложения?

Ответы [ 3 ]

2 голосов
/ 16 января 2012

Есть несколько способов, но проще всего было бы использовать file_save_upload():

$source = '/path/to/file.ext';
$dest = 'public://uploads/'; // Or whatever
$file = file_save_upload($source, array(), $dest, FILE_EXISTS_RENAME);

if ($file) {
  // file_save_upload marks the file as temporary, we need to mark as permanent or it will be cleared from the database in a few hours
  $file->status = FILE_STATUS_PERMANENT;
  file_save($file);
}
1 голос
/ 06 августа 2014

Это чуть не выбило меня из головы, и, пытаясь найти простой способ обойти ожидания 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 формы для начала. Я не знаю, кто начал это, но я должен был закончить это, и я сделал это с этим ужасным взломом. Надеюсь, это поможет вам или тому, кто еще вращается в друпальном вихре ужаса.

0 голосов
/ 11 сентября 2015

Мне удалось сделать следующее, чтобы добавить файл из папки public:// Drupal (обычно sites/default/files или sites/DOMAIN/files), используя file_save.

$uri = 'public://filename.pdf';
$file = file_save((object) array(
  'filename' => basename($uri),
  'uri' => $uri,
  'status' => FILE_STATUS_PERMANENT,
  'filemime' => file_get_mimetype($uri),
));

Это добавляет соответствующую запись в таблицу ядра Drupal file_managed. Если у вас установлен модуль File Entity , там также будет создана запись.

Возвращенный объект файла будет содержать идентификатор базы данных как $file->fid.

...