Hi
I'm working on a site which distributes content (PDF's) to multiple subsites using url's in an XML.
If I would start from scratch I'd use the existing filefield mapper with filefield, but the current implementation uses upload.module.

This is my (draft) code, it already takes care of retrieving the PDF's, storing them and adding them in the files table.
It's not attaching the file to the nodesthough. I'm probably doing something wrong?

/**
 * Implementation of hook_feeds_node_processor_targets_alter()
 */
function feeds_upload_mapper_feeds_node_processor_targets_alter(&$targets, $content_type) {
  $info = content_types($content_type);
  if (isset($info['extra']['attachments'])) {
  	$targets['attachment_field'] = array(
      'name' => t('Attachment'),
      'callback' => 'feeds_upload_mapper_feeds_set_target',
      'description' => t('The URL for the attachment @name field of the node.', array('@name' => $info['extra']['attachments']['name'])),
    );
  }
}

/**
 * Implementation of hook_feeds_set_target().
 *
 * @param $node
 *   The target node.
 * @param $field_name
 *   The name of field on the target node to map to.
 * @param $value
 *   The value to be mapped. 
 *
 */
function feeds_upload_mapper_feeds_set_target($node, $field_name, $value) {
	$path = pathinfo($value);
	
	$filedir = file_create_path('uploads');
	file_check_directory($filedir, FILE_CREATE_DIRECTORY);
	
	if(_feeds_upload_mapper_request($value)){
		$file = file_get_contents($value);
		$pathtofile = file_directory_path().'/uploads/'.$path['basename'];
		if(!file_exists($pathtofile)) {
			$file = file_save_data($file, $pathtofile, FILE_EXISTS_REPLACE);
			if($file){
			  $file = new stdClass();
			  $file->filename = $path['basename'];
			  $file->filepath = $pathtofile;
			  $file->filemime = file_get_mimetype($pathtofile);
			  $file->filesize = filesize($pathtofile);
			  $file->timestamp = time();
			  $file->status = 1;
			  $file->uid = 1;
			  drupal_write_record('files', $file);
			  $fid = db_last_insert_id('files', 'fid');
			  $file->description = $path['basename'];
			  $file->list = 1;
			  $file->weight= 0;
			  $node->files[$fid] = $file; // <-------- WHAT EXACTLY SHOULD I DO HERE TO MAKE THIS WORK??
			}
		}
	}
}

function _feeds_upload_mapper_request($url) {
	$request = drupal_http_request($url, array(), 'GET', NULL, 0);
	return ($request->code == '200' ? $request->data : FALSE);
}

any ideas?

CommentFileSizeAuthor
#3 feeds-core-upload-1160182-0.patch2.33 KBAzol
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

rv0’s picture

Priority: Normal » Minor

we decided switching to filefield anyway.

lowering priority and leaving this to "needs work" for anyone who might need this.

Azol’s picture

Status: Needs review » Needs work

I am in no way a Drupal pro, but this one works for me (based on rv0's code):

Filename upload.inc, should be put into feeds/mappers directory (without last ?>):

/**
* Implementation of hook_feeds_node_processor_targets_alter()
*/
function upload_feeds_node_processor_targets_alter(&$targets, $content_type) {
  $info = content_types($content_type);
  if (isset($info['extra']['attachments'])) {
      $targets['attachment_field'] = array(
      'name' => t('Attachment'),
      'callback' => 'upload_feeds_set_target',
      'description' => t('The core upload field'),
    );
  }
}

/**
* Implementation of hook_feeds_set_target().
*
* @param $node
*   The target node.
* @param $field_name
*   The name of field on the target node to map to.
* @param $value
*   The value to be mapped. 
*
*/
function upload_feeds_set_target(&$node, $field_name, $value) {
  $filedir = file_create_path('uploads');
  file_check_directory($filedir, FILE_CREATE_DIRECTORY);

  $enclosures = array();
  if (!is_array($value)) {
    $value = array($value);
  }
  foreach ($value as $k => $v) {
    if ($v instanceof FeedsEnclosure) {
      $enclosures[] = $v;
    }
  }
  
  foreach ($enclosures as $enclosure) {
    if ($file = $enclosure->getFile()) {
      $path = pathinfo($file);
      $filename = $path['basename'];
      // Going to transliterate the filename, since Feeds does not care to do it for local filenames
      if (function_exists('transliteration_clean_filename')) {
        $filename = transliteration_clean_filename($filename, language_default('language'));
      }
      $dest = file_directory_path().'/uploads/'.$filename;
      if (file_move($file, $dest, $replace = FILE_EXISTS_RENAME)) {
        $filepath = $file;
        $path = pathinfo($filepath);
        $file = new stdClass();
        $file->new = TRUE;
        $file->filepath = $filepath;
        $file->filename = $path['basename'];
        $file->filemime = file_get_mimetype($path['basename']);
        $file->filesize = filesize($filepath);
        $file->timestamp = time();
        $file->uid = 1;
        $file->description = $path['basename'];
        $file->list = 1;
        $file->weight = 0;
        drupal_write_record('files', $file);
        $fid = db_last_insert_id('files', 'fid');
        $node->files[$fid] = $file;
      }
    }
  }
}

Suggestions?

Azol’s picture

Assigned: Unassigned » Azol
Status: Needs work » Needs review
FileSize
2.33 KB

Created patch for #2

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 3: feeds-core-upload-1160182-0.patch, failed testing.

twistor’s picture

Assigned: Azol » Unassigned
Status: Needs work » Closed (outdated)