# This patch file was generated by NetBeans IDE
# This patch can be applied using context Tools: Apply Diff Patch action on respective folder.
# It uses platform neutral UTF-8 encoding.
# Above lines and this line are ignored by the patching process.
Index: contributions/modules/subscribe/subscribe.module
--- contributions/modules/subscribe/subscribe.module Base (1.27.2.7)
+++ contributions/modules/subscribe/subscribe.module Locally Modified (Based On 1.27.2.7)
@@ -423,10 +423,11 @@
       $node->nid = $local_nid;
 
       $local_node = node_load($local_nid);
+//watchdog('subscribe', print_r(array('local_node' => $local_node), TRUE));
       $node->vid = $local_node->vid;
 
       subscribe_remap_nodes($node);
-
+      subscribe_remap_filefields($node, $sid, $local_node);
       node_save($node);
       db_query('UPDATE {subscribe_node} SET exclude = 0 WHERE nid = %d', $node->nid);
       $u_counter = $u_counter + 1;
@@ -436,7 +437,7 @@
       $node->nid = '';
 
       subscribe_remap_nodes($node);
-
+      subscribe_remap_filefields($node, $sid);
       node_save($node);
       $local_nid = $node->nid;
       watchdog('subscribe', '%type: added %title from site %site.', array('%type' => $node->type, '%title' => $node->title, '%site' => $site_name), WATCHDOG_NOTICE, l(t('view'), 'node/'. $node->nid));
@@ -508,29 +509,101 @@
   if (!variable_get('upload_' . $node->type, 0)) {
     return;
   }
-  
+
+  $local_files = array();
   $result = db_query('SELECT * FROM {upload} u INNER JOIN {files} f ON u.fid = f.fid WHERE nid = %d', $node->nid);
-  while ($row = db_fetch_object($result)) {
-    file_delete($row->filepath);
-  }  
+  while ($row = db_fetch_array($result)) {
+    $local_files[] = $row;
+  }
+
+  subscribe_remap_files($local_files, $node->files, $node, $sid);
+
+  watchdog('subscribe', print_r(array(
+    'local' => $local_files,
+    'remote' => $node->files), TRUE));
+}
+
+/**
+ * Synchronises a list of files independenty of their site-specific ids.
+ *
+ * Two physical files are considered identical if their basename, size and timestamp match.
+ */
+function subscribe_remap_files($existing_files, &$incoming_files, $node, $sid) {
+
+  // Stuff local and remote file records into array,
+  // indexed by a composite portable keys, by which file equality may be considered.
+  $files = array('local' => array(), 'remote' => array());
+
+  foreach ($existing_files as $file) {
+    $files['local']["$file[filename]-$file[filesize]-$file[timestamp]"] = $file;
+  }
+
+  // Take reference as we gonna modify original record
+  foreach ($incoming_files as &$file) {
+    $files['remote']["$file[filename]-$file[filesize]-$file[timestamp]"] =& $file;
+  }
   
-  db_query('DELETE FROM {files} WHERE fid IN (SELECT fid FROM {upload} WHERE nid = %d)', $node->nid);
-  db_query('DELETE FROM {upload} WHERE nid = %d', $node->nid);
-  
-  if (!count($node->files)) {
-    return;
+  //For further processing select keys only
+  $keys = array(
+    'local' => array_keys($files['local']),
+    'remote' => array_keys($files['remote']),
+  );
+
+  // Sort out files to take appropriate actions on them
+  $new_keys = array(
+    'created' => array_diff($keys['remote'], $keys['local']),
+    //Just for completness - not actually needed..
+    'updated' => array_intersect($keys['remote'], $keys['local']),
+    'deleted' => array_diff($keys['local'], $keys['remote']),
+  );
+
+  // Collects file records ids and deletes physical files
+  $deleted_ids = array();
+  foreach ($new_keys['deleted'] as $key) {
+    $deleted_ids[] = $files['local'][$key]['fid'];
+    file_delete($files['local'][$key]['filepath']);
   }
 
-  $subscription = subscribe_subscription_load($sid);
+  // Deletes logical file records all at once
+  if (count($deleted_ids) > 0) {
+    $ids = implode(',', $deleted_ids);
+    db_query('DELETE FROM {files} WHERE fid IN (' . $ids .')');
+    db_query('DELETE FROM {upload} WHERE fid IN (' . $ids . ')');
+  }
+
+  //Mark files that need to be created by a temporary flag
+  foreach ($new_keys['created'] as $key) {
+    $files['remote'][$key]['is_new'] = TRUE;
+  }
   
-  foreach ($node->files as $file) {
-    $fileurl = $subscription->base_url . '/' . $file['filepath'];
-    $filedata = @file_get_contents($fileurl);
-    if (!$filedata) {
-      continue;
+  watchdog('subscribe', print_r(array(
+    'KEYS' => $new_keys,
+    'FILES' => $files), TRUE));
+
+  $subscription = subscribe_subscription_load($sid);
+
+  foreach ($files['remote'] as $key => & $file) {
+    $newfile = FALSE;
+    $is_new = $file['is_new'];
+    unset($file['is_new']);
+
+    if ($is_new) {
+      $fileurl = $subscription->base_url . '/' . $file['filepath'];
+      $filedata = @file_get_contents($fileurl);
+
+      if (!$filedata) {
+        continue;
+      }
+
+      $newfile = file_save_data($filedata, $file['filename']);
+      unset($file['fid']);
     }
-    
-    $newfile = file_save_data($filedata, $file['filename']);
+    else {
+      $newfile = $files['local'][$key]['filepath'];
+      // If there's matching local file then inherit it's ID
+      $file['fid'] = $files['local'][$key]['fid'];
+    }
+   
     if ($newfile) {
       $fileinfo = pathinfo($newfile);
       $file['filepath'] = $newfile;
@@ -539,12 +612,56 @@
       $file['vid'] = $node->vid;
       $file['uid'] = $node->uid;
 
-      drupal_write_record('files', $file);
-      drupal_write_record('upload', $file);
+      $update = $is_new ? array() : array('fid');
+
+      drupal_write_record('files', $file, $update);
+      
+      if (!isset($file['filefield_upload'])) {
+        drupal_write_record('upload', $file, $update);
+      }
     }
   }
 }
 
+function subscribe_remap_filefields(&$node, $sid, $local_node = FALSE) {
+  if (!module_exists('content')) {
+    return;
+  }
+
+  $field_names = array();
+
+  $content_fields = content_fields(NULL, $node->type);
+  foreach ($content_fields as $field) {
+    if($field['type'] == 'filefield') {
+      $field_names[] = $field['field_name'];
+    }
+  }
+
+  foreach ($field_names as $field_name) {
+    $field =& $node->{$field_name};
+    if (isset($field)) {
+      $local_field = array();
+      $nid = '';
+
+      if ($local_node) {
+        //$local_node = node_load();
+        $nid = $local_node->nid;
+        $local_field = $local_node->{$field_name};
+      }
+
+      foreach ($field as &$value) {
+        $value['nid'] = $nid;
+      }
+
+//watchdog('subscribe', print_r(array('field' => $field, 'local_field' => $local_field), TRUE));
+      subscribe_remap_files($local_field, $field, $node, $sid);
+      watchdog('subscribe', print_r(array(
+        'local' => $local_field,
+        'remote' => $field), TRUE));
+    }
+  }
+}
+
 function subscribe_remap_nodes(&$node) {
   if (!module_exists('content')) {
     return;
@@ -643,13 +760,13 @@
     return $ret;
   }
   
-  if (db_result(db_query('SELECT COUNT(*) FROM {subscribe_timestamp_nonce} WHERE domain = "%s" AND nonce = "%s"', $domain, $nonce))) {
+  if (db_result(db_query("SELECT COUNT(*) FROM {subscribe_timestamp_nonce} WHERE domain = '%s' AND nonce = '%s'", $domain, $nonce))) {
     $ret['status'] = 0;
     $ret['error'] = t('Token has been used previously for a request. Re-try with another nonce key.');
     return $ret;
   }
   else {
-    db_query('INSERT INTO {subscribe_timestamp_nonce} (domain, timestamp, nonce) VALUES ("%s", %d, "%s")', $domain, $timestamp, $nonce);
\ No newline at end of file
+    db_query("INSERT INTO {subscribe_timestamp_nonce} (domain, timestamp, nonce) VALUES ('%s', %d, '%s')", $domain, $timestamp, $nonce);
   }
   
   $hash_parameters = array($timestamp, $domain, $nonce, $method);
