Como adicionar programaticamente imagem de URL externa usando o módulo de mídia?

20

Desejo adicionar programaticamente uma imagem de uma URL externa e fazer com que o módulo armazene e exiba uma cópia local da imagem. Como eu posso fazer isso? Normalmente, eu clicaria no botão "selecionar mídia" ao criar um novo nó, mas desejo fazê-lo através do código.

Matthew Hui
fonte

Respostas:

0

Esta é uma resposta parcial à sua pergunta, pois estou tentando fazer algo semelhante, mas com material de vídeo.

Você pode criar o nó como um tipo de conteúdo, salvar o tipo de mídia que você precisa (consulte o código de mídia para ver o mime / tipo relevante e as funções que você precisa chamar). Você provavelmente precisará definir um campo de ativo multimídia e usar o seletor de arquivo de mídia no tipo de campo.

O problema com o qual estou tendo um problema é fazer com que o navegador o mostre no nó criado, no qual estou trabalhando atualmente.

ATUALIZAR

Tendo ido um pouco mais longe. Depois de salvar o arquivo de mídia (usando a API de mídia), associe o ID do arquivo ao ID do nó usando file_usage_add () . Você provavelmente também precisará associar o arquivo ao campo adicionado quando criou o campo de ativo de mídia.

ipê
fonte
Você não precisa chamar file_usage_add (). Você só precisa adicionar o arquivo a um campo como é mostrado na resposta do tecjam.
Dave Reid
13

Verifique se o seu php.ini permite allow_url_fopen. Então você pode usar algo parecido com isto em seu módulo:

$image = file_get_contents('http://drupal.org/files/issues/druplicon_2.png'); // string
$file = file_save_data($image, 'public://druplicon.png',FILE_EXISTS_REPLACE);

Use a função file_get_contents () do php

http://www.php.net/manual/en/function.file-get-contents.php

e use file_save_data () da API do Drupal

http://api.drupal.org/api/drupal/includes--file.inc/function/file_save_data/7

Então você poderá chamá-lo usando e salvá-lo em um nó etc.

$node = new stdClass;
$node->type = 'node_type';
node_object_prepare($node);
$node->field_image[LANGUAGE_NONE]['0']['fid'] = $file->fid;
node_save($node);

Editar:

Como apontado nos comentários, você pode usar a função system_retrieve_file Consulte: https://api.drupal.org/api/drupal/modules!system!system!system.module/function/system_retrieve_file/7

tecjam
fonte
8
Na verdade, existe uma API melhor para isso: system_retrieve_file () $file = system_retrieve_file('http://drupal.org/files/issues/druplicon_2.png', NULL, TRUE, FILE_EXISTS_RENAME);
Dave Reid
6

Aqui está o meu exemplo de trabalho.

$remoteDocPath = 'http://drupal.org/files/issues/druplicon_2.png';
$doc = system_retrieve_file($remoteDocPath, NULL, FALSE, FILE_EXISTS_REPLACE);
$file = drupal_add_existing_file($doc);

$node = new stdClass;
$node->type = 'node_type';
node_object_prepare($node);
$node->field_image[LANGUAGE_NONE]['0']['fid'] = $file->fid;
node_save($node);

function drupal_add_existing_file($file_drupal_path, $uid = 1, $status = FILE_STATUS_PERMANENT) {
  $files = file_load_multiple(array(), array('uri' => $file_drupal_path));
  $file = reset($files);

  if (!$file) {
    $file = (object) array(
        'filename' => basename($file_drupal_path),
        'filepath' => $file_drupal_path,
        'filemime' => file_get_mimetype($file_drupal_path),
        'filesize' => filesize($file_drupal_path),
        'uid' => $uid,
        'status' => $status,
        'timestamp' => time(),
        'uri' => $file_drupal_path,
    );
    drupal_write_record('file_managed', $file);
  }
  return $file;
}
hugronaphor
fonte
Por que você está criando um arquivo temporário com o arquivo system_retrieve_file()e salvando-o como permanente FILE_STATUS_PERMANENT? Não vejo o objetivo da sua função personalizada?
mpdonadio
Dessa forma - não tenho problemas com arquivos grandes.
precisa saber é o seguinte
1

Esta não é uma resposta direta, mas verifique se você já conhece o módulo Filefield Sources , que faz isso para imagens em geral. Pode atender às suas necessidades por conta própria; Não sei se é útil com a mídia.

rfay
fonte
0

Além da resposta do @tecjam: você deve usar drupal_http_request () em vez de file_get_contents () , ele oferece mais controle sobre o processo. Mas, no total, esse método funciona conforme o esperado.

Kirill Roskolii
fonte
0
// This is a PHP function to get a string representation of the image file.
$image = file_get_contents($path); 

// A stream wrapper path where you want this image to reside on your file system including the desired filename.
$destination = 'public://path/to/store/this/image/name.jpg'; 

$file = file_save_data($image, $destination, FILE_EXISTS_REPLACE);

if (is_object($file)) { // if you get back a Drupal $file object, everything went as expected so make the status permenant
  $file->status = 1;
  $file = file_save($file);
}

return $file;
mrded
fonte
Alguma razão para usar esse método system_retrieve_file()(o que faz tudo para você e evita problemas com servidores onde file_get_contents()não estão disponíveis)?
Clive