1

I am trying to create a node using last.fm.

$field = content_fields('field_my_image',"events"); //to get field
$validators = array_merge(filefield_widget_upload_validators($field), imagefield_widget_upload_validators($field)); //image validator
$files_path = filefield_widget_file_path($field); //save path
$src_path=$data->image[3]; // img url from last.fm eg: http://userserve-ak.last.fm/serve/252/502025.jpg
$file = field_file_save_file($src_path, $validators, $files_path, FILE_EXISTS_REPLACE);//save file
$nodenew->field_my_image = array(
                array(
                    'fid' => $file['fid'],
                    'title' => $file['filename'],
                    'filename' => $file['filename'],
                    'filepath' => $file['filepath'],
                    'filesize' => $file['filesize'],
                    'filemime' => $file['filemime'],
 ),
);//insert file details to node

Now the node is created, but no image and getting the message 'The selected file 502025.jpg could not be saved. The file is not a known image format.'

2
  • 1
    Welcome to Stack Overflow. Congratulations on finding an answer to your own question. Please post it as an answer (it's fine to answer your own question), which makes it clear to other people that the question has an answer. You can also mark your own answer as accepted, if no other answer was more helpful. Commented Feb 1, 2012 at 13:10
  • Better answers over at stackoverflow.com/q/5129559/1229018 Commented Feb 21, 2013 at 5:42

3 Answers 3

7

Drupal 7 provides a function for much of what you are doing: system_retrieve_file().

There ought to be a file module function for saving a file to Drupal based on a URL, but at least the function does exist... just not where anyone will look. You can use system_retrieve_file() with a third parameter of TRUE to create a managed file (calling file_save_data()).

Usage, a simpler example than Jav_Rock's but substantially the same, just skipping the hash path fanciness:

  $url = 'http://example.com/picture.png';
  $directory = file_build_uri('custom_directory');
  if (!file_prepare_directory($directory, FILE_CREATE_DIRECTORY)) {
    // If our directory doesn't exist and can't be created, use the default.
    $directory = NULL;
  }
  $file = system_retrieve_file($url, $directory, TRUE);
Sign up to request clarification or add additional context in comments.

Comments

2

update

Found the solution.

We need to save image to drupal folder first, by calling MODULENAME_save_image_local($url) in node creation function:

$src_path = MODULENAME_save_image_local($url);

add this function:

function MODULENAME_save_image_local($url) {
  $hash = md5($url);
  $dir = file_create_path('lastfm');
  if (!file_check_directory($dir)) {
    mkdir($dir, 0775, FALSE);
  }
  $hash = md5($url);
  $cachepath = file_create_path('CUSTOMFOLDERNAME/'. $hash.'.jpg');
  if (!is_file($cachepath)) {
    $result = eventpig_lastfm_fetch($url, $cachepath);
    if (!$result) {
      //we couldn't get the file
      return drupal_not_found();
    }
  }
  return file_directory_path() .'/CUSTOMFOLDERNAME/'. $hash.'.jpg';
}
/**
 * Api function to fetch a url and save image locally
*/
function MODULENAME_fetch($url, $cachepath) {
  if (!$url) {
    return drupal_not_found();
  }
  $result = drupal_http_request($url);
  $code   = floor($result->code / 100) * 100;
  $types  = array('image/jpeg', 'image/png', 'image/gif');
  if ($result->data && $code != 400 && $code != 500 && in_array($result->Content-Type, $types)) {
    $src = file_save_data($result->data, $cachepath);
  }
  else  {
    return drupal_not_found();
  }
  return TRUE;
}

Comments

1

Maybe it depends on url_fopen?
http://www.php.net/manual/en/filesystem.configuration.php#ini.allow-url-fopen

2 Comments

after testing, its confirmed that with this method, we cant save external image url .. have to find a way to save external url image to drupal file directory first! any suggestion?
perhaps you can make a system call to wget? <?php system('wget http://example.com/file > downloadfile')

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.