¿Cómo agregar mediante programación una imagen desde una URL externa usando un módulo de medios?

20

Quiero agregar mediante programación una imagen desde una URL externa y hacer que el módulo almacene y muestre una copia local de la imagen. ¿Cómo puedo hacer eso? Normalmente, haría clic en el botón "seleccionar medios" al crear un nuevo nodo, pero quiero hacerlo a través del código.

Matthew Hui
fuente

Respuestas:

0

Esta es una respuesta parcial a su pregunta, ya que estoy tratando de hacer algo similar pero con material de video.

Puede crear el nodo como un tipo de contenido, guardar el tipo de medio que necesita (eche un vistazo a través del código de medios para el mime / tipo relevante y las funciones que necesita llamar). Probablemente necesitará establecer un campo de activos multimedia y usar el selector de archivos multimedia en el tipo de campo.

Sin embargo, el problema con el que estoy teniendo problemas es hacer que el navegador lo muestre en el nodo creado, en el que estoy trabajando actualmente.

ACTUALIZAR

Habiendo llegado un poco más lejos. Una vez que haya guardado el archivo de medios (usando la API de medios), asocie la identificación del archivo con la ID del nodo usando file_usage_add () . Probablemente también deba asociar el archivo en el campo agregado cuando creó el campo de activo de medios.

ipe
fuente
No necesita llamar a file_usage_add (). Solo necesita agregar el archivo a un campo como se muestra en la respuesta de tecjam.
Dave Reid
13

Asegúrese de que su php.ini permita allow_url_fopen. Entonces puede usar algo como esto en su 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 la función php's file_get_contents ()

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

y luego use file_save_data () de la API de Drupal

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

Entonces debería poder llamarlo usando y guardarlo en un nodo, 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 se señaló en los comentarios, puede usar la función system_retrieve_file Consulte: https://api.drupal.org/api/drupal/modules!system!system.module/function/system_retrieve_file/7

tecjam
fuente
8
En realidad, hay una API mejor para esto: system_retrieve_file () $file = system_retrieve_file('http://drupal.org/files/issues/druplicon_2.png', NULL, TRUE, FILE_EXISTS_RENAME);
Dave Reid
6

Aquí está mi ejemplo de trabajo.

$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
fuente
¿Por qué está creando un archivo temporal con system_retrieve_file()y luego lo guarda como permanente FILE_STATUS_PERMANENT? ¿No veo el punto de su función personalizada?
mpdonadio
De esa manera, no tengo problemas con archivos grandes.
hugronaphor
1

Esta no es una respuesta directa, pero asegúrese de que ya conoce el módulo de fuentes de Filefield , que hace esto para las imágenes en general. Puede satisfacer sus necesidades por sí solo; No sé si es útil con los medios.

rfay
fuente
0

Además de la respuesta @tecjam: debe usar drupal_http_request () en lugar de file_get_contents () , le da más control sobre el proceso. Pero en total este método funciona como se esperaba.

Kirill Roskolii
fuente
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
fuente
¿Alguna razón para usar ese método system_retrieve_file()(que lo hace todo por usted y evita problemas con los servidores donde file_get_contents()no está disponible)?
Clive