Jak programowo dodać obraz z zewnętrznego adresu URL za pomocą modułu multimedialnego?

20

Chcę programowo dodać obraz z zewnętrznego adresu URL, aby moduł przechowywał i wyświetlał lokalną kopię obrazu. Jak mogę to zrobić? Zwykle klikałbym przycisk „wybierz media” podczas tworzenia nowego węzła, ale chcę to zrobić za pomocą kodu.

Matthew Hui
źródło

Odpowiedzi:

0

To jest częściowa odpowiedź na twoje pytanie, ponieważ próbuję zrobić coś podobnego, ale z materiałem wideo.

Możesz utworzyć węzeł jako typ zawartości, zapisać potrzebny typ multimediów (przejrzyj kod multimediów dla odpowiedniego MIME / typu i funkcji, które musisz wywołać). Prawdopodobnie będziesz musiał ustawić pole zasobu multimedialnego i użyć selektora plików multimedialnych w polu typu.

Problem z tym, że przeglądarka pokazuje go w utworzonym węźle, nad którym obecnie pracuję.

AKTUALIZACJA

Mając trochę dalej. Po zapisaniu pliku multimedialnego (za pomocą interfejsu API mediów) powiąż identyfikator pliku z identyfikatorem węzła za pomocą file_usage_add () . Prawdopodobnie konieczne będzie również powiązanie pliku w polu dodanym podczas tworzenia pola zasobu multimedialnego.

ipe
źródło
Nie musisz wywoływać file_usage_add (). Musisz tylko dodać plik do pola takiego, jak pokazano w odpowiedzi tecjam.
Dave Reid
13

Upewnij się, że twój php.ini pozwala allow_url_fopen. Następnie możesz użyć czegoś takiego w swoim module:

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

Użyj funkcji file_get_contents () php

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

a następnie użyj funkcji file_save_data () interfejsu API Drupala

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

Powinieneś być w stanie wywołać go za pomocą i zapisać go w węźle itp.

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

Edytować:

Jak wskazano w komentarzach, możesz użyć funkcji system_retrieve_file Patrz: https://api.drupal.org/api/drupal/modules!system!system.module/function/system_retrieve_file/7

tecjam
źródło
8
Właściwie istnieje lepszy interfejs API do tego: system_retrieve_file () $file = system_retrieve_file('http://drupal.org/files/issues/druplicon_2.png', NULL, TRUE, FILE_EXISTS_RENAME);
Dave Reid
6

Oto mój działający przykład.

$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
źródło
Dlaczego tworzysz plik tymczasowy za pomocą, system_retrieve_file()a następnie zapisujesz go jako plik stały FILE_STATUS_PERMANENT? Nie widzę sensu twojej niestandardowej funkcji?
mpdonadio
W ten sposób - nie mam problemów z dużymi plikami.
hugronaphor
1

To nie jest bezpośrednia odpowiedź, ale upewnij się, że wiesz już o module Filefield Sources , który robi to ogólnie dla obrazów. Może samodzielnie spełniać twoje potrzeby; Nie wiem, czy przydaje się to w Media.

rfay
źródło
0

Jako dodatek do @tecjam odpowiedź: powinieneś użyć drupal_http_request () zamiast file_get_contents () , daje to większą kontrolę nad procesem. Ale w sumie ta metoda działa zgodnie z oczekiwaniami.

Kirill Roskolii
źródło
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
źródło
Czy jest jakiś powód, aby użyć tej metody system_retrieve_file()(co to wszystko dla Ciebie i pozwala uniknąć problemów z serwerami, które file_get_contents()nie są dostępne)?
Clive