'admin/node/scheduler', 'title' => t('schedule'), 'callback' => 'scheduler_admin', 'access' => user_access('administer nodes') && user_access('schedule nodes'), 'type' => MENU_LOCAL_TASK); } return $items; } function scheduler_settings() { $form['scheduler_form_mode'] = array( '#type' => 'radios', '#title' => t('Form display mode'), '#default_value' => variable_get('scheduler_form_mode', 0), '#options' => array( '0' => t('Allow post and hide scheduling'), '1' => t('Only allow post scheduling'), '2' => t('Only allow hide scheduling'), ), '#description' => t('What options should the scheduler form offer?'), ); return $form; } function scheduler_write($node, $op, $arg) { if (user_access('schedule nodes')) { $conds = array(); if ($node->scheduler_post) { $conds['timestamp_posted'] = scheduler_nodetime($node, 'post'); } else { $conds['timestamp_posted'] = 0; } if ($node->scheduler_hide) { $conds['timestamp_hidden'] = scheduler_nodetime($node, 'hide'); } else { $conds['timestamp_hidden'] = 0; } // No schedule needs to take place (works for update and insert too) if (array_sum($conds) == 0) { scheduler_remove_schedule($node); return; } if ($op !== 'insert') { // Determine whether we must UPDATE or INSERT, then do it $result = db_query('SELECT * FROM {scheduler} WHERE nid = %d', $node->nid); if (db_num_rows($result)) { foreach ($conds as $key => $value) { $update_conds[] = "$key=$value"; } db_query('UPDATE {scheduler} SET %s WHERE nid = %d', implode(', ', $update_conds), $node->nid); } else { scheduler_insert_schedule($node, $conds); } } else { scheduler_insert_schedule($node, $conds); } } } function scheduler_insert_schedule($node, $conds) { $conds['nid'] = $node->nid; db_query('INSERT INTO {scheduler} (%s) VALUES (%s)', implode(', ', array_keys($conds)), implode(', ', array_values($conds))); } function scheduler_remove_schedule($node) { db_query('DELETE FROM {scheduler} WHERE nid = %d', $node->nid); } /** * Implementation of hook_nodeapi(). */ function scheduler_nodeapi(&$node, $op, &$arg) { static $error; switch ($op) { case 'validate': if (user_access('schedule nodes')) { if ($node->scheduler_post) { if (!checkdate($node->scheduler_post_month, $node->scheduler_post_day, $node->scheduler_post_year)) { form_set_error('scheduler_post', t('Invalid scheduled post date set; automatically adjusted')); $error['scheduler_post'] = theme('error', t('Invalid date set, automatically adjusted')); } else { $post_date = scheduler_nodetime($node, 'post'); if (time() > $post_date) { form_set_error('scheduler_post', t('Scheduled post date in the past')); $error['scheduler_post'] = theme('error', t('Date in the past')); } // Automatically depublish node if date is fine else { $node->status = 0; } } } if ($node->scheduler_hide) { if (!checkdate($node->scheduler_hide_month, $node->scheduler_hide_day, $node->scheduler_hide_year)) { form_set_error('scheduler_hide', t('Invalid scheduled hide date set; automatically adjusted')); $error["scheduler_hide"] = theme("error", t('Invalid date set, automatically adjusted')); } else { $hide_date = scheduler_nodetime($node, 'hide'); if (time() > $hide_date) { form_set_error('scheduler_hide', t('Scheduled hide date in the past')); $error["scheduler_hide"] = theme("error", t('Date in the past')); } } } } break; case 'insert': scheduler_write($node, $op, $arg); break; case 'update': scheduler_write($node, $op, $arg); break; case 'delete': scheduler_remove_schedule($node); break; } } /** * Implementation of hook_form_alter(). */ function scheduler_form_alter($form_id, &$form) { if (isset($form['type']) && $form['type']['#value'] .'_node_form' == $form_id) { if (user_access('schedule nodes')) { // Build up date components array $month_names = array(1 => t('January'), t('February'), t('March'), t('April'), t('May'), t('June'), t('July'), t('August'), t('September'), t('October'), t('November'), t('December')); $date_components = array( 'year' => array('Y', drupal_map_assoc(range(date('Y'), date('Y')+5))), 'month' => array('m', $month_names), 'day' => array('d', drupal_map_assoc(range(1, 31))), 'hour' => array('H', drupal_map_assoc(range(0, 23))), 'minute' => array('i', drupal_map_assoc(range(0, 59))) ); // 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.
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.
Do not check the enabling checkbox unless you want to schedule this document.')) ); // Get edit information from post if possible $node = isset($form['#node']) ? $form['#node'] : NULL; if (isset($_POST['edit']) && count($_POST['edit'])) { $edit = (object) $_POST['edit']; if ($edit->scheduler_post) { $form_elements['scheduler_post'][0] = scheduler_nodetime($edit, 'post'); $form_elements['scheduler_post'][1] = TRUE; } if ($edit->scheduler_hide) { $form_elements['scheduler_hide'][0] = scheduler_nodetime($edit, 'hide'); $form_elements['scheduler_hide'][1] = TRUE; } } elseif ($node->nid) { $result = db_query('SELECT timestamp_hidden, timestamp_posted FROM {scheduler} WHERE nid = %d', $node->nid); $schedule = db_fetch_object($result); if ($schedule->timestamp_posted) { $form_elements['scheduler_post'][0] = $schedule->timestamp_posted; $form_elements['scheduler_post'][1] = TRUE; } if ($schedule->timestamp_hidden) { $form_elements['scheduler_hide'][0] = $schedule->timestamp_hidden; $form_elements['scheduler_hide'][1] = TRUE; } } // Hide controls if admin requested switch (variable_get('scheduler_form_mode', 0)) { case 0: // Allow both controls break; case 1: // Allow post control unset($form_elements['scheduler_hide']); break; case 2: // Allow hide control unset($form_elements['scheduler_post']); break; } // Compose form to post and hide nodes $form['scheduler'] = array( '#type' => 'fieldset', '#title' => t('Scheduling'), '#weight' => 26, '#collapsible' => TRUE, '#collapsed' => TRUE, ); foreach ($form_elements as $fname => $felem) { $form['scheduler'][$fname]['begin'] = array( '#type' => 'markup', '#value' => '
', ); $form['scheduler'][$fname][$fname] = array( '#type' => 'checkbox', '#value' => $felem[1], '#suffix' => t('Enabled'), ); foreach ($date_components as $dname => $ddata) { if ($dname == 'hour' && strpos(variable_get('date_format_medium', 'D, Y-m-d H:i'), 'g:ia')) { $form['scheduler'][$fname][$fname .'_'. $dname] = array( '#type' => 'select', '#default_value' => date($ddata[0], $felem[0]), '#options' => drupal_map_assoc($ddata[1], '_scheduler_hour_format'), ); } else { $form['scheduler'][$fname][$fname .'_'. $dname] = array( '#type' => 'select', '#default_value' => date($ddata[0], $felem[0]), '#options' => $ddata[1], ); } } $form['scheduler'][$fname]['end'] = array( '#type' => 'markup', '#value' => '
'. $felem[3] .'
', ); } } } } /** * Implementation of hook_perm(). */ function scheduler_perm() { return array('schedule nodes'); } function _scheduler_hour_format($hour) { if ($hour == 0) { return t('12 am'); } if ($hour == 12) { return t('12 pm'); } if ($hour > 12) { $hour = $hour - 12; return t('%hour pm', array('%hour' => $hour)); } else { return t('%hour am', array('%hour' => $hour)); } } 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()); $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) { db_query('DELETE FROM {scheduler} WHERE nid = %d', $node->nid); } // This node needs to be hidden later, 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()); $numhide = db_num_rows($result); while ($node = db_fetch_object($result)) { // Hide node and remove schedule entry db_query('UPDATE {node} SET status = 0 WHERE nid = %d', $node->nid); db_query('DELETE FROM {scheduler} WHERE nid = %d', $node->nid); } if ($numhide || $numpost) { watchdog('special', t('Scheduler posted %numpost nodes and hid %numhide nodes.', array('%numpost' => $numpost, '%numhide' => $numhide))); // Clear cache so anonymous users see changes cache_clear_all(); } } //TODO: provide more options for filtering function scheduler_admin() { $header = array( array('data' => t('Title'), 'field' => 'n.title'), 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('Operations'), 'colspan' => 2) ); // Default ordering if (!isset($_GET['order']) && !isset($_GET['sort'])) { $_GET['order'] = t('Post'); $_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); $result = pager_query($sql, 50); while ($node = db_fetch_object($result)) { $rows[] = array( ($node->status ? l($node->title, "node/$node->nid") : $node->title), theme('username', $node), ($node->timestamp_posted ? format_date($node->timestamp_posted) : ' '), ($node->timestamp_hidden ? format_date($node->timestamp_hidden) : ' '), l(t('edit'), 'node/'. $node->nid .'/edit'), l(t('delete'), "admin/node/delete/$node->nid") ); } if (count($rows)) { if ($pager = theme('pager', NULL, 50, 0)) { $rows[] = array(array('data' => $pager, 'colspan' => 6)); } return theme('table', $header, $rows); } else { return t('There are no scheduled nodes.'); } } // Return the time of post or hide operation on the node function scheduler_nodetime(&$node, $type = 'post') { if (!in_array($type, array('post', 'hide'))) { return time(); } else { return mktime( $node->{"scheduler_{$type}_hour"}, $node->{"scheduler_{$type}_minute"}, rand(0, 59), $node->{"scheduler_{$type}_month"}, $node->{"scheduler_{$type}_day"}, $node->{"scheduler_{$type}_year"} ); } } ?>