Index: advpoll-form.js
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/advpoll/advpoll-form.js,v
retrieving revision 1.1.2.3
diff -u -p -r1.1.2.3 advpoll-form.js
--- advpoll-form.js	30 Jul 2007 20:36:39 -0000	1.1.2.3
+++ advpoll-form.js	12 Aug 2007 03:29:37 -0000
@@ -50,29 +50,10 @@ Drupal.advpoll.removeChoiceClick = funct
   });
 }
 
-Drupal.advpoll.updateStartDate = function() {
-  if ($("#edit-settings-usestart").attr("checked")) {
-    $(".edit-settings-startdate").show();
-    $("#edit-settings-startdate-year").removeAttr("disabled");
-    $("#edit-settings-startdate-month").removeAttr("disabled");
-    $("#edit-settings-startdate-day").removeAttr("disabled");
-  }
-  else {
-    $(".edit-settings-startdate").hide();
-    $("#edit-settings-startdate-year").attr("disabled", "disabled");
-    $("#edit-settings-startdate-month").attr("disabled", "disabled");
-    $("#edit-settings-startdate-day").attr("disabled", "disabled");
-  }
-}
-
 Drupal.advpoll.nodeFormAutoAttach = function() {
   // Hide "need more choices" checkbox
   $("#morechoices").hide();
   
-  // Disable starting date if necessary
-  Drupal.advpoll.updateStartDate();
-  $("#edit-settings-usestart").click(Drupal.advpoll.updateStartDate);
-  
   // Insert Remove links
   $('<a class="remove-choice">' + Drupal.settings.advPoll.remove + '</a>').insertAfter("input.choices");
   Drupal.advpoll.removeChoiceClick();
Index: advpoll.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/advpoll/advpoll.install,v
retrieving revision 1.5.2.11
diff -u -p -r1.5.2.11 advpoll.install
--- advpoll.install	12 Aug 2007 03:19:21 -0000	1.5.2.11
+++ advpoll.install	12 Aug 2007 05:20:31 -0000
@@ -15,11 +15,11 @@ function advpoll_install() {
         mode varchar(32) NOT NULL,
         uselist tinyint default '0',
         active tinyint default '1',
-        runtime int NOT NULL default '0',
         maxchoices int unsigned NOT NULL default '0',
         algorithm VARCHAR(100),
         showvotes tinyint,
-        startdate int unsigned,
+        startdate int NOT NULL default '0',
+        enddate int NOT NULL default '0',
         PRIMARY KEY (nid)
       ) /*!40100 DEFAULT CHARACTER SET utf8 */");
 
@@ -45,11 +45,11 @@ function advpoll_install() {
         mode varchar(32) NOT NULL,
         uselist smallint DEFAULT '0',
         active smallint DEFAULT '1',
-        runtime integer NOT NULL DEFAULT '0',
         maxchoices integer NOT NULL DEFAULT '0',
         algorithm varchar(100),
         showvotes smallint,
-        startdate integer,
+        startdate integer NOT NULL DEFAULT '0',
+        enddate integer NOT NULL DEFAULT '0',
         PRIMARY KEY (nid)
       )");
 
@@ -143,3 +143,38 @@ function advpoll_update_2() {
   }
   return $ret;
 }
+
+/**
+ * Switch date handling from a duration to an enddate.
+ */
+function advpoll_update_3() {
+  $ret = array();
+  
+  switch ($GLOBALS['db_type']) {
+    case 'mysql':
+    case 'mysqli':
+      // New default '0' instead of NULL for startdate
+      $ret[] = update_sql("ALTER TABLE {advpoll} CHANGE startdate startdate int NOT NULL DEFAULT '0'");
+      $ret[] = update_sql("UPDATE {advpoll} SET startdate = 0 WHERE startdate IS NULL");
+      // Add the new column.
+      $ret[] = update_sql("ALTER TABLE {advpoll} ADD COLUMN enddate int NOT NULL default '0' AFTER startdate");
+      // Calculate the new value.
+      $ret[] = update_sql("UPDATE {advpoll} SET enddate = startdate + runtime WHERE runtime != 0");
+      // Drop the old column.
+      $ret[] = update_sql("ALTER TABLE {advpoll} DROP COLUMN runtime");
+      break;
+    
+    case 'pgsql':
+      // New default '0' instead of NULL for startdate
+      db_change_column($ret, 'advpoll', 'startdate', 'startdate', 'integer', array('not null' => TRUE, 'default' => '0'));
+      $ret[] = update_sql("UPDATE {advpoll} SET startdate = 0 WHERE startdate IS NULL");
+      // Add the new column.
+      db_add_column($ret, 'advpoll', 'enddate', 'integer', array('not null' => TRUE, 'default' => '0'));
+      // Calculate the new value.
+      $ret[] = update_sql("UPDATE {advpoll} SET enddate = startdate + runtime WHERE runtime != 0");
+      // Drop the old column.
+      db_drop_column($ret, 'advpoll', 'runtime');
+      break;
+  }
+  return $ret;
+}
Index: advpoll.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/advpoll/advpoll.module,v
retrieving revision 1.21.2.54
diff -u -p -r1.21.2.54 advpoll.module
--- advpoll.module	11 Aug 2007 20:58:26 -0000	1.21.2.54
+++ advpoll.module	12 Aug 2007 05:49:39 -0000
@@ -82,7 +82,7 @@ function advpoll_page() {
   $result = pager_query($sql, 15);
   $output = '<ul>';
   while ($node = db_fetch_object($result)) {
-    $output .= '<li>'. l($node->title, "node/$node->nid") .' - '. format_plural($node->votes, '1 vote', '@count votes') .' - '. ($node->active ? t('open') : t('closed')) .'</li>';
+    $output .= '<li>'. l($node->title, "node/$node->nid") .' - '. format_plural($node->votes, '1 vote', '@count votes') .' - '. (_advpoll_is_active($node) ? t('open') : t('closed')) .'</li>';
   }
   $output .= '</ul>';
   $output .= theme('pager', NULL, 15);
@@ -108,29 +108,6 @@ function advpoll_votingapi_calculate(&$r
   }
 }
 
-
-/**
- * Implementation of hook_cron().
- *
- * Closes polls that have exceeded their allowed runtime.
- */
-function advpoll_cron() {
-  // Open polls with a startdate that is in the past but that need to be opened
-  $sql = 'SELECT p.nid FROM {advpoll} p WHERE p.startdate IS NOT NULL AND (p.runtime = 0 OR p.startdate + p.runtime >= '. (time() - time() % (3600 * 24)) .') AND p.startdate < '. time() .' AND p.active = 0';
-  $result = db_query($sql);
-  while ($poll = db_fetch_object($result)) {
-    db_query("UPDATE {advpoll} SET active = 1 WHERE nid=%d", $poll->nid);
-  }
-
-  // Close polls
-  $sql = 'SELECT p.nid FROM {advpoll} p INNER JOIN {node} n ON p.nid = n.nid WHERE ((p.startdate IS NULL AND (n.created + p.runtime) < '. time() .') OR (p.startdate IS NOT NULL AND (p.startdate + p.runtime) < '. time() .')) AND p.active = 1 AND p.runtime != 0';
-  $result = db_query($sql);
-  while ($poll = db_fetch_object($result)) {
-    db_query("UPDATE {advpoll} SET active = 0 WHERE nid=%d", $poll->nid);
-  }
-}
-
-
 /**
  * Implementation of hook_delete().
  */
@@ -152,7 +129,6 @@ function advpoll_delete($node) {
 function advpoll_form($node, $form_values = NULL) {
   $mode = _advpoll_get_mode($node->type);
   $type = node_get_types('type', $node);
-  
   // Only add javascript once, even if _form is called multiple times.
   static $add_js;
   if (!$add_js) {
@@ -260,48 +236,36 @@ function advpoll_form($node, $form_value
     );
   }
 
-  $active = array(1 => t('Active'), 0 => t('Closed'));
   $form['settings']['active'] = array(
-    '#type' => 'radios',
-    '#title' => t('Status'),
-    '#options' => $active,
-    '#default_value' => (isset($node->active)? $node->active : 1),
-    '#description' => t('When a poll is closed users may no longer vote on it.'),
-  );
-
-  $_duration = array(0 => t('Unlimited')) + drupal_map_assoc(array(86400, 172800, 345600, 604800, 1209600, 2419200, 4838400, 9676800, 31536000), 'format_interval');
-
-  $form['settings']['usestart'] = array(
     '#type' => 'checkbox',
-    '#title' => t('Use start date'),
-    '#description' => t('Specify a date that the poll opens.'),
-    '#default_value' => (isset($node->startdate)? TRUE :
-      ($form_values['startdate']? $form_values['startdate'] : FALSE)),
+    '#title' => t('Close poll'),
+    '#description' => t('When a poll is closed users may no longer vote on it.'),
+    '#default_value' => (isset($node->active) ? !$node->active : 0),
   );
 
-  $date = $form_values['startdate']? $form_values['startdate'] :
-    $node->startdate? $node->startdate : time();
-
   $form['settings']['startdate'] = array(
-    '#prefix' => '<div class="edit-settings-startdate">',
-    '#suffix' => '</div>',
-    '#type' => 'date',
+    '#type' => 'textfield',
     '#title' => t('Starting date'),
-    '#description' => t('Date that the poll opens'),
-    '#default_value' => array('year' => date('Y', $date), 'month' => date('n', $date), 'day' => date('d', $date)),
-  );
-
-  $form['settings']['startdatejs'] = array(
-    '#type' => 'hidden',
-    '#default_value' => $date,
+    '#description' => t('The date that the poll opens. Leave blank if you want the poll to open now.'),
+    '#size' => 25,
+    '#maxlength' => 25,
+    '#default_value' => $node->startdate ? format_date($node->startdate, 'custom', 'Y-m-d H:i:s O') : (variable_get('advpoll_runtime_'. $type->type, FALSE) ? format_date(time(), 'custom', 'Y-m-d H:i:s O') : ''),
   );
-
-  $form['settings']['runtime'] = array(
-    '#type' => 'select',
-    '#title' => t('Duration'),
-    '#default_value' => ($node->runtime ? $node->runtime : variable_get('advpoll_runtime_'. $type->type, ADVPOLL_RUNTIME)),
-    '#options' => $_duration,
-    '#description' => t('After this period, the poll will be closed automatically. This is relative to the start date if it is specified, otherwise the date the poll was created.')
+  
+  $default_enddate = '';
+  // Specify enddate if default duration is set and we are creating, not
+  // updating, a node.
+  if (variable_get('advpoll_runtime_'. $type->type, FALSE) && !isset($node->nid)) {
+    $default_enddate =  format_date(time() + variable_get('advpoll_runtime_'. $type->type, ''), 'custom', 'Y-m-d H:i:s O');
+  }
+  
+  $form['settings']['enddate'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Ending date'),
+    '#description' => t('The date that the poll closes. Leave blank if you do not want the poll to close automatically.'),
+    '#size' => 25,
+    '#maxlength' => 25,
+    '#default_value' => $node->enddate ? format_date($node->enddate, 'custom', 'Y-m-d H:i:s O') : $default_enddate,
   );
 
   $form['settings']['uselist'] = array(
@@ -515,8 +479,7 @@ function advpoll_menu($may_cache) {
       // Make sure we're on the actual poll node's page
       if (strstr($node->type, 'advpoll_') == 0) {
         // Show the results tab
-        if ($node->active && !$node->voted
-          && _advpoll_can_view_results($node)) {
+        if (_advpoll_is_active($node) && !$node->voted && _advpoll_can_view_results($node)) {
           $items[] = array(
             'path' => 'node/'. $nid .'/results',
             'title' => t('Results'),
@@ -812,7 +775,7 @@ function advpoll_tab_votes() {
  */
 function _advpoll_can_view_results($node) {
   $view_results = variable_get('advpoll_view_results_'. $node->type, ADVPOLL_VIEW_RESULTS);
-  return (!$node->active  // Node is closed
+  return (!_advpoll_is_active($node)  // Node is closed
         || ($node->voted && $view_results == 'aftervote') // User voted
         || ($view_results == 'always')); // All can view
 }
@@ -861,7 +824,7 @@ function advpoll_update($node) {
     $node->settings['active'] = _advpoll_calculate_active($node);
   }
 
-  db_query("UPDATE {advpoll} SET active=%d, runtime=%d, maxchoices=%d, algorithm='%s', uselist=%d, showvotes=%d, startdate='%s' WHERE nid = %d", $node->settings['active'], $node->settings['runtime'], $node->settings['maxchoices'], $node->settings['algorithm'], $node->settings['uselist'], $node->settings['showvotes'], $node->settings['usestart'] ? _advpoll_create_startdate($node) : 'NULL', $node->nid);
+  db_query("UPDATE {advpoll} SET active = %d, maxchoices = %d, algorithm = '%s', uselist = %d, showvotes = %d, startdate = '%s', enddate = '%s' WHERE nid = %d", $node->settings['active'], $node->settings['maxchoices'], $node->settings['algorithm'], $node->settings['uselist'], $node->settings['showvotes'], $node->settings['startdate'] ? strtotime($node->settings['startdate']) : 0, $node->settings['enddate'] ? strtotime($node->settings['enddate']) : 0, $node->nid);
 
   _advpoll_insert_choices($node->nid);
   votingapi_recalculate_results('advpoll', $node->nid);
@@ -869,33 +832,28 @@ function advpoll_update($node) {
 
 
 /**
- * Determine if node should be active for _insert and _update operations.
- *
- * This function is needed when changing the startdate and/or duration.
+ * Helper function to check if a poll is active.
  */
-function _advpoll_calculate_active($node) {
-  $startdate = _advpoll_create_startdate($node);
-  if ($node->settings['runtime']) {
-    // Check that startdate is in the past and that the duration hasn't elapsed
-    $active = time() >= $startdate
-      && time() < $node->settings['runtime'] + $startdate;
-  }
-  else {
-    // Just need to ensure that startdate is in the past
-    $active = time() >= $startdate;
+function _advpoll_is_active($node) {
+  $active = $node->active;
+  $startdate = $node->startdate;
+  $enddate = $node->enddate;
+
+  if (!$active) {
+    return $active;
+   }
+
+  if (isset($startdate)) {
+    // Check that startdate is in the past.
+     $active = time() >= $startdate;
+   }
+
+  if ($active && isset($enddate)) {
+    // Check that enddate is in the future.
+    $active = time() < $enddate;
   }
-  return $active? 1 : 0;
-}
 
-/*
- * Create a unix timestamp for startdate based on FormAPI inputs.
- */
-function _advpoll_create_startdate($node) {
-  list($hour, $min) = explode(':', date('h:m', time()));
-  return mktime($hour, $min, 0,
-      $node->settings['startdate']['month'],
-      $node->settings['startdate']['day'],
-      $node->settings['startdate']['year']);
+  return $active;
 }
 
 function _advpoll_insert_choices($nid) {
@@ -927,11 +885,7 @@ function _advpoll_get_mode($node_type) {
  */
 function advpoll_insert($node) {
   $mode = _advpoll_get_mode($node->type);
-  if ($node->settings['usestart']) {
-    $node->settings['active'] = _advpoll_calculate_active($node);
-  }
-
-  db_query("INSERT INTO {advpoll} (nid, mode, uselist, active, runtime, maxchoices, algorithm, showvotes, startdate) VALUES (%d, '%s', %d, %d, %d, %d, '%s', %d, '%s')", $node->nid, $mode, $node->settings['uselist'], $node->settings['active'], $node->settings['runtime'], $node->settings['maxchoices'], $node->settings['algorithm'], $node->settings['showvotes'], $node->settings['usestart'] ? _advpoll_create_startdate($node) : 'NULL');
+  db_query("INSERT INTO {advpoll} (nid, mode, uselist, active, maxchoices, algorithm, showvotes, startdate, enddate) VALUES (%d, '%s', %d, %d, %d, '%s', %d, '%s', '%s')", $node->nid, $mode, $node->settings['uselist'], !$node->settings['active'], $node->settings['maxchoices'], $node->settings['algorithm'], $node->settings['showvotes'], $node->settings['startdate'] ? strtotime($node->settings['startdate']) : 0, $node->settings['enddate'] ? strtotime($node->settings['enddate']) : 0);
 
   // Insert the choices
   _advpoll_insert_choices($node->nid);
@@ -1035,7 +989,7 @@ function advpoll_view($node, $teaser = F
       '#value' => drupal_get_form('advpoll_voting_'. $mode .'_form', $node, $teaser, $page),
     );
   }
-  else if (!$node->voted && arg(2) != 'results' && $node->active) {
+  else if (!$node->voted && arg(2) != 'results' && _advpoll_is_active($node)) {
     // User hasn't voted and we're not on the results tab
     $node->content['poll'] = array(
       '#weight' => 1,
@@ -1083,7 +1037,7 @@ function theme_advpoll_results($title, $
 
 function _advpoll_show_cancel_form($node) {
   $output = '';
-  if ($node->voted && $node->cancel_vote && user_access('cancel own vote') && $node->active) {
+  if ($node->voted && $node->cancel_vote && user_access('cancel own vote') && _advpoll_is_active($node)) {
     $output .= drupal_get_form('advpoll_cancel_form', $node->nid);
   }
   return $output;
@@ -1155,7 +1109,7 @@ function advpoll_cancel($nid) {
   global $user;
   $nid = arg(2);
   if ($node = node_load(array('nid' => $nid))) {
-    if ($node->voted && $node->active) {
+    if ($node->voted && _advpoll_is_active($node)) {
       if ($user->uid && count(votingapi_get_user_votes('advpoll', $node->nid)) > 0) {
         votingapi_unset_vote('advpoll', $node->nid, $user->uid);
       }
