# 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/userpoints/userpoints.install
--- contributions/modules/userpoints/userpoints.install Base (1.15.2.3)
+++ contributions/modules/userpoints/userpoints.install Locally Modified (Based On 1.15.2.3)
@@ -84,6 +84,12 @@
         'not null' => TRUE,
         'default' => 0,
       ),
+      'changed' => array(
+        'description' => t('Efective timestamp of last action on this transaction, for tracking purposes.'),
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
       'status' => array(
         'description' => t('Status'),
         'type' => 'int',
@@ -148,6 +154,8 @@
       'operation' => array('operation'),
       'reference' => array('reference'),
       'status' => array('status'),
+      //Optional as in update_6011
+      'changed' => array('changed'),
     )
   );
   return $schema;
@@ -243,3 +251,23 @@
   $ret[] = update_sql("UPDATE {permission} SET perm = REPLACE(perm, 'admin userpoints', 'administer userpoints') WHERE perm LIKE '%admin userpoints%'");
   return $ret;
 }
+
+/*
+ * From: http://drupal.org/node/395500
+ * "time_stamp parameter is not considered in userpoints api"
+ */
+function userpoints_update_6011() {
+  $ret = array();
+  db_add_field($ret, 'userpoints_txn', 'changed', array(
+    'type' => 'int',
+    'not null' => TRUE,
+    'default' => 0,
+    'description' => t("Efective timestamp of last action on this transaction, for tracking purposes."),
+    )
+  );
+//Optional: An index could help about tracking operations so it would be better to define here..
+  db_add_index($ret, 'userpoints_txn', 'changed', array('changed'));
+//Optional: update table information to mark each transaction as changed on creation only..
+  $ret[] = update_sql("UPDATE {userpoints_txn} SET changed = time_stamp");
+  return $ret;
+}
Index: contributions/modules/userpoints/userpoints.module
--- contributions/modules/userpoints/userpoints.module Base (1.67.2.42)
+++ contributions/modules/userpoints/userpoints.module Locally Modified (Based On 1.67.2.42)
@@ -38,6 +38,7 @@
 define('USERPOINTS_CATEGORY_DEFAULT_VID', 'userpoints_category_default_vid');
 define('USERPOINTS_CATEGORY_DEFAULT_TID', 'userpoints_category_default_tid');
 define('USERPOINTS_CATEGORY_PROFILE_DISPLAY_TID', 'userpoints_category_profile_display_tid');
+define('USERPOINTS_TRANSACTION_TIMESTAMP', 'userpoints_transaction_timestamp');
 
 
 /**
@@ -445,6 +446,21 @@
 	    '#description' => t('Select which category of !points to display on the user profile page. Select "All" to display a sum total of all categories', userpoints_translation()),
 	  );
   }
+  // New configuration options to overide current timestamp
+  $group = "stamping";
+  $form[$group] = array(
+    '#type' => 'fieldset',
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+    '#title' => t('Transaction stamping'),
+    '#description' => t(''),
+  );
+  $form[$group][USERPOINTS_TRANSACTION_TIMESTAMP] = array(
+    '#type'          => 'checkbox',
+    '#title'         => t('Always use system time'),
+    '#default_value' => variable_get(USERPOINTS_TRANSACTION_TIMESTAMP, 1),
+    '#description'   => t('Sets if the transaction timestamp should obey current time, or can be modified by the API operations. Unchecking this option will allow customization of timetamp for the transactions.'),
+  );
 
   $form['setting'] = module_invoke_all('userpoints', 'setting');
   return system_settings_form($form);
@@ -495,6 +511,7 @@
  *    'points' => # of points (int) (required)
  *    'moderate' => TRUE/FALSE 
  *    'uid' => $user->uid 
+ *    'time_stamp' => unix time of the points assignement date
  *    'operation' => 'published' 'moderated' etc.
  *    'tid' => 'category ID' 
  *    'expirydate' => timestamp or 0, 0 = non-expiring; NULL = site default
@@ -510,7 +527,6 @@
  *     'reason' => (string) error message to indicate reason for failure
  */
 function userpoints_userpointsapi($params) {
-
   //Test for the existence of parameters and set defaults if necessary
   if (!isset($params['txn_id'])) {
     //If a txn_id is passed in we'll do an UPDATE thus the std checks don't apply
@@ -705,6 +721,16 @@
       $params['expirydate'] = userpoints_get_default_expiry_date();
     }
   } // if txn_id
+
+  //Control times_tamp functionality, by default with current timestamp
+  $time = time();
+  //overide system time if meeting criteria matches: Don't let future timestamps, Don't let bad formated timestamps
+  if (variable_get(USERPOINTS_TRANSACTION_TIMESTAMP, 0) || !isset($params['time_stamp']) || !is_numeric($params['time_stamp']) || $params['time_stamp'] > $time || $params['time_stamp'] < 0) {
+      $params['time_stamp'] = $time;
+  }
+  //Always force changed timestamp to current time() for transaction tracking
+  $params['changed'] = $time;
+
   if (is_numeric($params['txn_id'])) {
     //A transaction ID was passed in so we'll update the transaction
     $result = db_query("SELECT txn_id, uid, approver_uid, points, 
@@ -714,41 +740,21 @@
       WHERE txn_id = %d",
       $params['txn_id']);
     $txn = db_fetch_array($result);
-    foreach ($txn as $key => $value) {
-      if (isset($params[$key])) {
-        $arr[] = $key .' = \''. $params[$key] .'\'';
-      } 
-      else {
-        $params[$key] = $value;
-      }
-    }
 
-    db_query('UPDATE {userpoints_txn} SET '. implode(', ', $arr) .' 
-              WHERE txn_id = %d',
-              $params['txn_id']
-            );
+    //don't superseed existing keys, just complete missing keys
+    $params += $txn;
+    //Update existing transaction record for key txn_id
+    $ret = drupal_write_record('userpoints_txn', $params, array('txn_id'));
+    //Only update if the record has been successfully updated
+    if ($ret != FALSE) {
     _userpoints_update_cache($params);
   }
+  }
   else {
-    $ret = db_query("INSERT INTO {userpoints_txn}
-      (uid, points, time_stamp, status, operation, description, 
-      reference, expirydate, expired, parent_txn_id, tid, entity_id, entity_type)
-      VALUES (%d, %d, %d, %d, '%s', '%s', '%s', %d, %d, %d, %d, %d, '%s')",
-      $params['uid'],
-      $params['points'],
-      time(),
-      $params['status'],
-      $params['operation'],
-      $params['description'],
-      $params['reference'],
-      $params['expirydate'],
-      $params['expired'], 
-      $params['parent_txn_id'],
-      $params['tid'],
-      $params['entity_id'],
-      $params['entity_type']
-    );
-    if ($params['status'] != true && $ret != false) {
+    //Create new transaction record
+    $ret = drupal_write_record('userpoints_txn', $params);
+    //don't cache entry if it's pending
+    if ($params['status'] != TRUE && $ret != FALSE) {
       _userpoints_update_cache($params);
     }
   }
@@ -1236,6 +1242,7 @@
                   'description' => $form_state['values']['description'],
                   'reference' => $form_state['values']['reference'],
                   'tid' => $form_state['values']['tid'],
+                  'time_stamp' => strtotime($form_state['values']['time_stamp']),
                 );
       if ($form_state['values']['expirydate']) {
         //Check for the existence of an expirydate 
