--- cvs/scheduler.module	Thu Dec  9 21:08:03 2004
+++ modules/scheduler/scheduler.module	Thu Dec  9 21:03:03 2004
@@ -27,7 +27,7 @@
 }
 
 function scheduler_write($node, $op, $arg) {
-  if (user_access('schedule nodes') && ($node->scheduler_post || $node->scheduler_hide)) {
+  if (user_access('schedule nodes') && ($node->scheduler_post || $node->scheduler_hide || $node->scheduler_promote || $scheduler_demote)) {
 
     if ($node->scheduler_post) {
       $conds['timestamp_posted'] = scheduler_nodetime($node, 'post');
@@ -41,6 +41,18 @@
     else {
       $conds['timestamp_hidden'] = 0;
     }
+    if ($node->scheduler_promote) {
+      $conds['timestamp_promote'] = scheduler_nodetime($node, 'promote');
+    }
+    else {
+      $conds['timestamp_promote'] = 0;
+    }
+    if ($node->scheduler_demote) {
+      $conds['timestamp_demote'] = scheduler_nodetime($node, 'demote');
+    }
+    else {
+      $conds['timestamp_demote'] = 0;
+    }
 
     if ($op !== 'insert') {
       // Determine whether we must UPDATE or INSERT, then do it
@@ -103,6 +115,37 @@
             }
           }
         }
+
+        if ($node->scheduler_promote) {
+          if (!checkdate($node->scheduler_promote_month, $node->scheduler_promote_day, $node->scheduler_promote_year)) {
+            form_set_error('scheduler_promote', t('Invalid scheduled promote date set; automatically adjusted'));
+            $error['scheduler_promote'] = theme('error', t('Invalid date set, automatically adjusted'));
+          } else {
+            $promote_date = scheduler_nodetime($node, 'promote');
+            if (time() > $promote_date) {
+              form_set_error('scheduler_promote', t('Scheduled promote date in the past'));
+              $error['scheduler_promote'] = theme('error', t('Date in the past'));
+            }
+            // Automatically demote node if date is fine
+            else {
+              $node->promote = 0;
+            }
+          }
+        }
+
+        if ($node->scheduler_demote) {
+          if (!checkdate($node->scheduler_demote_month, $node->scheduler_demote_day, $node->scheduler_demote_year)) {
+            form_set_error('scheduler_demote', t('Invalid scheduled demote date set; automatically adjusted'));
+            $error['scheduler_demote'] = theme('error', t('Invalid date set, automatically adjusted'));
+          } else {
+            $demote_date = scheduler_nodetime($node, 'demote');
+            if (time() > $demote_date) {
+              form_set_error('scheduler_demote', t('Scheduled demote date in the past'));
+              $error['scheduler_demote'] = theme('error', t('Date in the past'));
+            }
+          }
+        }
+
       }
       break;
     case 'insert':
@@ -127,7 +170,9 @@
         // Form element specs (time, enabled, title, description)
         $form_elements = array(
           'scheduler_post' => array(time(), FALSE, t('Automatically post document'), t('The date at which your document will be automatically posted.<br />Do not check the enabling checkbox unless you want to schedule this document.')),
-          'scheduler_hide' => array(time(), FALSE, t('Automatically hide document'), t('The date at which your document will be automatically hidden.<br />Do not check the enabling checkbox unless you want to schedule this document.'))
+          'scheduler_hide' => array(time(), FALSE, t('Automatically hide document'), t('The date at which your document will be automatically hidden.<br />Do not check the enabling checkbox unless you want to schedule this document.')),
+          'scheduler_promote' => array(time(), FALSE, t('Automatically promote document'), t('The date at which your document will be automatically promoted to the front page.<br />Do not check the enabling checkbox unless you want to schedule this document.')),
+          'scheduler_demote' => array(time(), FALSE, t('Automatically demote document'), t('The date at which your document will be automatically demoted from the front page.<br />Do not check the enabling checkbox unless you want to schedule this document.'))
         );
 
         // Get edit information from post if possible
@@ -141,11 +186,19 @@
             $form_elements['scheduler_hide'][0] = scheduler_nodetime($edit, 'hide');
             $form_elements['scheduler_hide'][1] = TRUE;
           }
+          if ($edit->scheduler_promote) {
+            $form_elements['scheduler_promote'][0] = scheduler_nodetime($edit, 'promote');
+            $form_elements['scheduler_promote'][1] = TRUE;
+          }
+          if ($edit->scheduler_demote) {
+            $form_elements['scheduler_demote'][0] = scheduler_nodetime($edit, 'demote');
+            $form_elements['scheduler_demote'][1] = TRUE;
+          }
         }
 
         // Preserve the data set in the DB (if there was no form)
         elseif ($node->nid) {
-          $result = db_query('SELECT timestamp_hidden, timestamp_posted FROM {scheduler} WHERE nid = %d', $node->nid);
+          $result = db_query('SELECT timestamp_hidden, timestamp_posted, timestamp_promote, timestamp_demote FROM {scheduler} WHERE nid = %d', $node->nid);
           $schedule = db_fetch_object($result);
           if ($schedule->timestamp_posted) {
             $form_elements['scheduler_post'][0] = $schedule->timestamp_posted;
@@ -156,6 +209,14 @@
             $form_elements['scheduler_hide'][1] = TRUE;
           // $form .= form_item($felem[2], $form_item, $felem[3]);
           }
+          if ($schedule->timestamp_promote) {
+            $form_elements['scheduler_promote'][0] = $schedule->timestamp_promote;
+            $form_elements['scheduler_promote'][1] = TRUE;
+          }
+          if ($schedule->timestamp_demote) {
+            $form_elements['scheduler_demote'][0] = $schedule->timestamp_demote;
+            $form_elements['scheduler_demote'][1] = TRUE;
+          }
         }
 
         // Compose form to post and hide nodes
@@ -204,32 +265,74 @@
 
 function scheduler_cron() {
   // If we are past the posting time, then post.
-  $result = db_query('SELECT s.nid, s.timestamp_posted, s.timestamp_hidden FROM {scheduler} s LEFT JOIN {node} n ON s.nid = n.nid WHERE n.status = 0 AND s.timestamp_posted > 0 AND s.timestamp_posted < %d', time());
+  $result = db_query('SELECT s.nid, s.timestamp_posted, s.timestamp_hidden, s.timestamp_promote, s.timestamp_demote FROM {scheduler} s LEFT JOIN {node} n ON s.nid = n.nid WHERE n.status = 0 AND s.timestamp_posted > 0 AND s.timestamp_posted < %d', time());
   $numpost = db_num_rows($result);
   while ($node = db_fetch_object($result)) {
     db_query('UPDATE {node} SET created = %d, changed = %d, status = 1 WHERE nid = %d', $node->timestamp_posted, $node->timestamp_posted, $node->nid);
     
-    // No hide information for node, no need to keep record
-    if ($node->timestamp_hidden == 0) {
+    // No other scheduled actions for node, no need to keep record
+    if ($node->timestamp_hidden == 0 && $node->timestamp_promote == 0 && $node->timestamp_demote == 0) {
       db_query('DELETE FROM {scheduler} WHERE nid = %d', $node->nid);
     }
-    // This node needs to be hidden later, only set posted to empty
+    // This node has more scheduled actions, only set posted to empty
     else {
       db_query('UPDATE {scheduler} SET timestamp_posted = 0 WHERE nid = %d', $node->nid);
     }
   }
 
   //  If we are past the hide time, then hide.
-  $result = db_query('SELECT s.nid FROM {scheduler} s LEFT JOIN {node} n ON s.nid = n.nid WHERE n.status = 1 AND s.timestamp_hidden > 0 AND s.timestamp_hidden < %d', time());
+  $result = db_query('SELECT s.nid, s.timestamp_posted, s.timestamp_promote, s.timestamp_demote FROM {scheduler} s LEFT JOIN {node} n ON s.nid = n.nid WHERE n.status = 1 AND s.timestamp_hidden > 0 AND s.timestamp_hidden < %d', time());
   $numhide = db_num_rows($result);
   while ($node = db_fetch_object($result)) {
-    // Hide node and remove schedule entry
+    // Hide node
     db_query('UPDATE {node} SET status = 0 WHERE nid = %d', $node->nid);
-    db_query('DELETE FROM {scheduler} WHERE nid = %d', $node->nid);
+
+    // No other scheduled actions for node, no need to keep record
+    if ($node->timestamp_posted && $node->timestamp_promote == 0 && $node->timestamp_demote == 0) {
+      db_query('DELETE FROM {scheduler} WHERE nid = %d', $node->nid);
+    }
+    // This node has more scheduled actions, only set posted to empty
+    else {
+      db_query('UPDATE {scheduler} SET timestamp_hidden = 0 WHERE nid = %d', $node->nid);
+    }
+  }
+
+  //  If we are past the promote time, then promote.
+  $result = db_query('SELECT s.nid, s.timestamp_posted, s.timestamp_hidden, s.timestamp_promote, s.timestamp_demote FROM {scheduler} s LEFT JOIN {node} n ON s.nid = n.nid WHERE n.promote = 0 AND s.timestamp_promote > 0 AND s.timestamp_promote < %d', time());
+  $numpromote = db_num_rows($result);
+  while ($node = db_fetch_object($result)) {
+    // Promote node
+    db_query('UPDATE {node} SET promote = 1, changed = %d WHERE nid = %d', $node->timestamp_promote, $node->nid);
+
+    // No other scheduled actions for node, no need to keep record
+    if ($node->timestamp_posted == 0 && $node->timestamp_hidden = 0 && $node->timestamp_demote == 0) {
+      db_query('DELETE FROM {scheduler} WHERE nid = %d', $node->nid);
+    }
+    // This node has more scheduled actions, only set posted to empty
+    else {
+      db_query('UPDATE {scheduler} SET timestamp_promote = 0 WHERE nid = %d', $node->nid);
+    }
+  }
+
+  //  If we are past the demote time, then demote.
+  $result = db_query('SELECT s.nid, s.timestamp_posted, s.timestamp_hidden, s.timestamp_promote, s.timestamp_demote FROM {scheduler} s LEFT JOIN {node} n ON s.nid = n.nid WHERE n.promote = 1 AND s.timestamp_demote > 0 AND s.timestamp_demote < %d', time());
+  $numdemote = db_num_rows($result);
+  while ($node = db_fetch_object($result)) {
+    // Demote node
+    db_query('UPDATE {node} SET promote = 0, changed = %d WHERE nid = %d', $node->timestamp_demote, $node->nid);
+
+    // No other scheduled actions for node, no need to keep record
+    if ($node->timestamp_posted == 0 && $node->timestamp_hidden == 0 && $node->timestamp_promote == 0) {
+      db_query('DELETE FROM {scheduler} WHERE nid = %d', $node->nid);
+    }
+    // This node has more scheduled actions, only set posted to empty
+    else {
+      db_query('UPDATE {scheduler} SET timestamp_demote = 0 WHERE nid = %d', $node->nid);
+    }
   }
 
-  if ($numhide || $numpost) {
-    watchdog('special', t('Scheduler posted %numpost nodes and hid %numhide nodes.', array('%numpost' => $numpost, '%numhide' => $numhide)));
+  if ($numhide || $numpost || $numpromote || $numdemote) {
+    watchdog('special', t('Scheduler posted %numpost nodes, hid %numhide nodes, promoted %numpromote nodes, and demoted %numdemote nodes.', array('%numpost' => $numpost, '%numhide' => $numhide, '%numpromote' => $numpromote, '%numdemote' => $numdemote)));
     // Clear cache so anonymous users see changes
     cache_clear_all();
   }
@@ -242,6 +345,8 @@
     array('data' => t('Author'), 'field' => 'u.name'),
     array('data' => t('Post'), 'field' => 's.timestamp_posted'),
     array('data' => t('Hide'), 'field' => 's.timestamp_hidden'),
+    array('data' => t('Promote'), 'field' => 's.timestamp_promote'),
+    array('data' => t('Demote'), 'field' => 's.timestamp_demote'),
     array('data' => t('Operations'), 'colspan' => 2)
   );
 
@@ -251,7 +356,7 @@
     $_GET['sort'] = 'desc';
   }
 
-  $sql = 'SELECT n.nid, n.uid, n.status, u.name, n.title, s.timestamp_posted, s.timestamp_hidden FROM {scheduler} s LEFT JOIN {node} n ON s.nid = n.nid LEFT JOIN {users} u ON n.uid = u.uid' . tablesort_sql($header);
+  $sql = 'SELECT n.nid, n.uid, n.status, u.name, n.title, s.timestamp_posted, s.timestamp_hidden, s.timestamp_promote, s.timestamp_demote FROM {scheduler} s LEFT JOIN {node} n ON s.nid = n.nid LEFT JOIN {users} u ON n.uid = u.uid' . tablesort_sql($header);
   $result = pager_query($sql, 50);
 
   while ($node = db_fetch_object($result)) {
@@ -260,6 +365,8 @@
       format_name($node),
       ($node->timestamp_posted ? format_date($node->timestamp_posted) : '&nbsp;'),
       ($node->timestamp_hidden ? format_date($node->timestamp_hidden) : '&nbsp;'),
+      ($node->timestamp_promote ? format_date($node->timestamp_promote) : '&nbsp;'),
+      ($node->timestamp_demote ? format_date($node->timestamp_demote) : '&nbsp;'),
       l(t('edit'), 'node/'. $node->nid .'/edit'),
       l(t('delete'), "admin/node/delete/$node->nid")
     );
@@ -289,7 +396,7 @@
 
 // Return the time of post or hide operation on the node
 function scheduler_nodetime(&$node, $type = 'post') {
-  if (!in_array($type, array('post', 'hide'))) {
+  if (!in_array($type, array('post', 'hide', 'promote', 'demote'))) {
     return time();
   }
   else {
