I noticed that node.getNodeFiles doesn't return files for CCK filefield/imagefield. I was able to write my own method easily enough to accomplish this, and borrowed this bit of code from file_service.inc:


if (count($files) > 0) {
	  $send = array();
	  foreach ($files as $file) {
		$file = array_shift($files);
		
		$filepath = file_create_path($file['filepath']);
		$binaryfile = fopen($filepath, 'rb');
		$send[$file['fid']] = array(
		  'file'      => base64_encode(fread($binaryfile, filesize($filepath))),
		  'filename'  => $file['filename'],
		  'uid'       => $file['uid'],
		  'filemime'  => $file['filemime'],
		  'filesize'  => $file['filesize'],
		  'status'    => $file['status'],
		  'timestamp' => $file['timestamp']
		);
		fclose($binaryfile);
	  }
	}	
		return $send;
	} else {
		return services_error(t('There are no files on given node.'));
	}

On the receiving end, I see the file on the server, in the database, and in the files system in Drupal. Everything about the file looks right, it has the right file size, name, file type.

When I try to open the PDF, it says that it's 'not a PDF' and could be corrupted/damaged.

Here is how I am saving that file on the remote site, which is code I used to save images from xml responses in the same manner. It worked for that, so I thought it would also work here:

  if (count($files)) {
				
					foreach ($files as $remote_file) {
						$upload_directory = file_directory_path();

						if (file_check_directory($upload_directory, 1)) {
							$upload_destination = $upload_directory . '/' . $remote_file['filename'];
							
							$file_data = $remote_file['file'];
													
							$file_check = file_save_data($file_data, $upload_destination, $replace = FILE_EXISTS_REPLACE);
							
							// is $file_check true, and, is $file_check a valid image?
						
							if ($file_check) {
								// Load up the CCK field
								$field = content_fields('field_floorplan', 'homes');
								
								// Load up the appropriate validators
								$validators = array_merge(filefield_widget_upload_validators($field), filefield_widget_upload_validators($field));
								
								// Where do we save the file?
								$files_path = filefield_widget_file_path($field);
								
								// Create the file object, replace existing file with new file as source and dest are the same
								$file = field_file_save_file($file_check, $validators, $files_path, NULL);
								
								$node->field_floorplan[] = $file;

							} else {
								// error message log
								watchdog('homes_sync', 'Error during file upload to @dir directory.', array('@dir' => $upload_directory), WATCHDOG_CRITICAL);
							}	
						} else {
							watchdog('homes_sync', 'Error creating @dir directory.', array('@dir' => $upload_directory), WATCHDOG_CRITICAL);
						}
					}	
				
				}

     node_save($node);

Everything looks right, only the PDF won't open up. Is there something wrong with the base64 method being used for PDFs?

Comments

kevinquillen’s picture

Got it, needed to add base64_decode when setting $file_data. PDFs are good now.

But, can anyone tell why the file is duplicated under the files directory? I have the original file, and a _0 file of the same name. It keeps adding, even though its being told FILE_EXISTS_REPLACE.

kevinquillen’s picture

Can anyone help me out? This is confusing. I have looked at countless examples. The only result I can get is duplicate files come in. Example, first cron run I will get somefile.pdf. Then run it again, I will get somefile_0.pdf. If somefile.pdf already exists, it should overwrite it, not make unique. Also, there are file fragments like fileMkmdf that are 0 bytes. I don't see where that is coming through in the code either.

kylebrowning’s picture

Status: Active » Closed (works as designed)

getNodeFiles only returns attached files from the Upload module. You're better off using views_service and grabbing the cck fields that way.