# HG changeset patch
# Parent 21e600454f9a22756d11e02d22ea02b3649e7df0
Decisions: Make the node_save(node_load(X)) construct works.

Both decisions_inserts and decisions_updates assumes that their
values come from a form submission, and thus use the values as
they would appear in a form api submit callback.

That's not always the case though, and a lot of both contrib
and even core assumes that a basic construct around the lines
of

  $node = node_load(NID);
  // Do something with $node
  node_save($node);

is a safe way to update node properties.

With this patch, this construct should work again.

diff --git a/decisions.module b/decisions.module
--- a/decisions.module
+++ b/decisions.module
@@ -1197,10 +1197,60 @@
   }
   $decision->choices = count($decision->choice);
   $decision->vote = decisions_get_vote($node->nid, $user->uid);
+
+  // Format the settings in an array similar to the tree that
+  // we would get from a form submission.
+  $decision->settings = array();
+  foreach (decisions_member_settings_map() as $key => $parents) {
+    $value = $decision->$key;
+    decisions_array_set_nested_value($decision->settings, $parents, $value);
+  }
+  // Add some special calculated properties to our settings array.
+  $decision->settings['date']['noenddate'] = ($decision->runtime == DECISIONS_RUNTIME_INFINITY);
+  $decision->settings['date']['enddate'] = array(
+    'date' => $decision->startdate + $decision->runtime
+  );
   return $decision;
 }
 
 /**
+ * Maps the values stored directly in the database to their parents
+ * array in the settings form.
+ */
+function decisions_member_settings_map() {
+  return array(
+    'algorithm' => array('algorithm'),
+    'uselist' => array('uselist'),
+    'active' => array('active'),
+    'showvotes' => array('showvotes'),
+    'maxchoices' => array('maxchoices'),
+    'randomize' => array('randomize'),
+    'quorum_abs' => array('quorum', 'quorum_abs'),
+    'quorum_percent' => array('quorum', 'quorum_percent'),
+    'startdate' => array('date', 'startdate', 'date')
+  );
+}
+
+/**
+ * Sets a value in a nested array with variable depth.
+ *
+ * This helper function should be used when the depth of the array element you
+ * are changing may vary (that is, the number of parent keys is variable).
+ * It is primarily used for form structures and renderable arrays.
+ *
+ * This function is a straight copy from Drupal 7 drupal_array_set_nested_value.
+ */
+function decisions_array_set_nested_value(&$array, array $parents, $value) {
+  $ref = &$array;
+  foreach ($parents as $parent) {
+     // Note that PHP is fine with referencing a not existing array key - in this
+     // case it just creates an entry with NULL as value.
+     $ref = &$ref[$parent];
+   }
+   $ref = $value;
+}
+
+/**
  * Implementation of hook_delete().
  *
  */
@@ -1220,12 +1270,18 @@
  */
 function decisions_insert($node) {
   // Compute startdate and runtime.
-  $startdate = _decisions_translate_form_date($node->settings['date']['startdate']['date']);
+  $startdate = $node->settings['date']['startdate']['date'];
+  if (is_array($startdate)) {
+    $startdate = _decisions_translate_form_date($startdate);
+  }
   if ($node->settings['date']['noenddate']) {
     $runtime = DECISIONS_RUNTIME_INFINITY;
   }
   else {
-    $enddate = _decisions_translate_form_date($node->settings['date']['enddate']['date']);
+    $enddate = $node->settings['date']['enddate']['date'];
+    if (is_array($enddate)) {
+      $enddate = _decisions_translate_form_date($enddate);
+    }
     if ($enddate < $startdate) {
       form_set_error('enddate', t('The specified close date is less than the opening date, setting it to the same for now.'));
       $enddate = $startdate;
@@ -1287,12 +1343,19 @@
  */
 function decisions_update($node) {
   // Compute startdate and runtime.
-  $startdate = _decisions_translate_form_date($node->settings['date']['startdate']['date']);
+  $startdate = $node->settings['date']['startdate']['date'];
+  if (is_array($startdate)) {
+    $startdate = _decisions_translate_form_date($startdate);
+  }
+
   if ($node->settings['date']['noenddate']) {
     $runtime = DECISIONS_RUNTIME_INFINITY;
   }
   else {
-    $enddate = _decisions_translate_form_date($node->settings['date']['enddate']['date']);
+    $enddate = $node->settings['date']['enddate']['date'];
+    if (is_array($enddate)) {
+      $enddate = _decisions_translate_form_date($enddate);
+    }
     if ($enddate < $startdate) {
       form_set_error('enddate', t('The specified close date is less than the opening date, setting it to the same for now.'));
       $enddate = $startdate;
@@ -1857,4 +1920,4 @@
     'content_id_column' => 'nid',
   );
   return $relationships;
-}
\ No newline at end of file
+}
