? poormanscron.test
Index: poormanscron.admin.inc
===================================================================
RCS file: poormanscron.admin.inc
diff -N poormanscron.admin.inc
--- poormanscron.admin.inc	27 Apr 2008 09:40:29 -0000	1.1.2.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,35 +0,0 @@
-<?php
-// $Id: poormanscron.admin.inc,v 1.1.2.1 2008/04/27 09:40:29 robloach Exp $
-
-/**
- * @file
- * Provides the administration page for Poormanscron.
- */
-  
-/**
- * Administration page for Poormanscron.
- */
-function poormanscron_admin_settings() {
-  $form['time_intervals'] = array('#type' => 'fieldset', '#title' => t('Time intervals'));
-  $form['time_intervals']['poormanscron_interval'] = array(
-    '#type' => 'textfield', '#title' => t('Cron runs interval'),
-    '#default_value' => variable_get('poormanscron_interval', 60),
-    '#size' => 5, '#maxlength' => 10,
-    '#description' => t('Minimum number of minutes between cron runs. Cron will actually execute during the first page request after the interval has elapsed.')
-  );
-  $form['time_intervals']['poormanscron_retry_interval'] = array(
-    '#type' => 'textfield', '#title' => t('Retry interval'),
-    '#default_value' => variable_get('poormanscron_retry_interval', 10),
-    '#size' => 5, '#maxlength' => 10,
-    '#description' => t('The number of minutes to wait after a cron run error before retrying.')
-  );
-
-  $form['logging'] = array('#type' => 'fieldset', '#title' => t('Logging'));
-  $form['logging']['poormanscron_log_cron_runs'] = array(
-    '#type' => 'select', '#title' => t('Log successful cron runs'),
-    '#default_value' => variable_get('poormanscron_log_cron_runs', 1),
-    '#options' => array('1' => t('Yes'), '0' => t('No')),
-    '#description' => t('If you want to log successful cron runs to the Drupal watchdog, say Yes here. If those messages annoy you, disable them by selecting No.')
-  );
-  return system_settings_form($form);
-}
Index: poormanscron.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/poormanscron/Attic/poormanscron.install,v
retrieving revision 1.1.2.1
diff -u -p -r1.1.2.1 poormanscron.install
--- poormanscron.install	11 Feb 2008 07:28:14 -0000	1.1.2.1
+++ poormanscron.install	27 Sep 2009 19:22:40 -0000
@@ -5,6 +5,14 @@
  * Implementation of hook_uninstall().
  */
 function poormanscron_uninstall() {
-  db_query("DELETE FROM {variable} WHERE name LIKE 'poormanscron_%'");
-  cache_clear_all('variables', 'cache');
+  variable_del('poormanscron_interval');
+  variable_del('poormanscron_retry_interval');
+  variable_del('poormanscron_log_cron_runs');
+}
+
+function poormanscron_update_6200() {
+  variable_set('cron_safe_threshold', variable_get('poormanscron_interval', 60) * 60);
+  variable_del('poormanscron_interval');
+  variable_del('poormanscron_retry_interval');
+  variable_del('poormanscron_log_cron_runs');
 }
Index: poormanscron.js
===================================================================
RCS file: poormanscron.js
diff -N poormanscron.js
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ poormanscron.js	27 Sep 2009 19:22:40 -0000
@@ -0,0 +1,16 @@
+// $Id$
+
+/**
+ * Checks to see if the cron should be automatically run.
+ */
+Drupal.behaviors.cronCheck = function(context) {
+  if (Drupal.settings.cronCheck || false) {
+    $('body:not(.cron-check-processed)', context).addClass('cron-check-processed').each(function() {
+      // Only execute the cron check if its the right time.
+      if (Math.round(new Date().getTime() / 1000.0) > Drupal.settings.cronCheck) {
+        alert('Running cron!');
+        $.get(Drupal.settings.basePath + 'poormanscron/run-cron-check');
+      }
+    });
+  }
+};
Index: poormanscron.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/poormanscron/poormanscron.module,v
retrieving revision 1.21.2.2
diff -u -p -r1.21.2.2 poormanscron.module
--- poormanscron.module	6 May 2009 05:07:08 -0000	1.21.2.2
+++ poormanscron.module	27 Sep 2009 19:22:41 -0000
@@ -7,88 +7,108 @@
  */
 
 /**
- * Implementation of hook_help().
+ * Default interval for automatic cron executions in seconds.
  */
-function poormanscron_help($path, $arg) {
-  switch ($path) {
-    case 'admin/help#poormanscron':
-      return '<p>'. t('The Poormanscron module runs cron jobs without the need of the cron application.') .'</p>';
-    case 'admin/settings/poormanscron':
-      return '<p>'. t('The settings provided here allow you to administer Poormancron.') .'</p>';
-  }
+if (!defined('DRUPAL_CRON_DEFAULT_THRESHOLD')) {
+  define('DRUPAL_CRON_DEFAULT_THRESHOLD', 10800);
+}
+
+if (!defined('REQUEST_TIME')) {
+  define('REQUEST_TIME', time());
 }
 
 /**
- * Implementation of hook_exit().
- *
- * Checks if poormanscron needs to be run. If this is the case, it invokes
- * the cron hooks of all enabled modules, which are executed after
- * all HTML is returned to the browser. So the user who kicks off the cron
- * jobs should not notice any delay.
- */
-function poormanscron_exit() {
-
-  // Calculate when the next poormanscron run is due.
-  $lastrun = variable_get('poormanscron_lastrun', 0);
-  $nextrun = $lastrun + 60 * variable_get('poormanscron_interval', 60);
-
-  // If the configured time has passed, start the next poormanscron run.
-  if (time() > $nextrun) {
-
-    // If this cron run fails to complete, wait a few minutes before retrying.
-    variable_set('poormanscron_lastrun',
-       $lastrun + 60 * variable_get('poormanscron_retry_interval', 10));
-
-    // Get the current Drupal messages. Use drupal_set_message() so that
-    // the messages aren't deleted in case the cron run fails and
-    // we don't get a chance to restore them below.
-    $saved_messages = drupal_set_message();
-
-    // Invoke the cron hooks of all enabled modules.
-    if (drupal_cron_run()) {
-      $message = 'Cron run completed (via poormanscron).';
-    }
-    else {
-      $message = 'Cron run unsuccessful (via poormanscron).';
-    }
+ * Implementation of hook_menu().
+ */
+function poormanscron_menu() {
+  $items['poormanscron/run-cron-check'] = array(
+    'title' => 'Execute cron',
+    'page callback' => 'poormanscron_run_cron_check',
+    'access callback' => 'poormanscron_run_cron_check_access',
+    'type' => MENU_CALLBACK,
+  );
+  return $items;
+}
 
-    // Write a message to the logs if the user wants us to do so.
-    if (variable_get('poormanscron_log_cron_runs', 1) == 1) {
-      watchdog('cron', $message);
-    }
+/**
+ * Implementation of hook_init().
+ */
+function poormanscron_init() {
+  if (poormanscron_run_cron_check_access()) {
+    drupal_add_js(drupal_get_path('module', 'poormanscron') . '/poormanscron.js');
+    drupal_add_js(array('cronCheck' => REQUEST_TIME + variable_get('cron_safe_threshold', DRUPAL_CRON_DEFAULT_THRESHOLD)), 'setting');
+  }
+}
 
-    $t = time();
+/**
+ * Checks if the feature to automatically run cron is enabled.
+ *
+ * Also used as a menu access callback for this feature.
+ *
+ * @return
+ *   TRUE if cron threshold is enabled, FALSE otherwise.
+ *
+ * @see poormanscron_run_cron_check()
+ */
+function poormanscron_run_cron_check_access() {
+  return variable_get('cron_safe_threshold', DRUPAL_CRON_DEFAULT_THRESHOLD) > 0;
+}
 
-    // Update the time of the last poormanscron run (this one).
-    variable_set('poormanscron_lastrun', $t);
+/**
+ * Menu callback; executes cron via an image callback.
+ *
+ * This callback runs cron in a separate HTTP request to prevent "mysterious"
+ * slow-downs of regular HTTP requests. It is invoked via an AJAX request
+ * (if the client's browser supports JavaScript).
+ *
+ * @see poormanscron_run_cron_check_access()
+ */
+function poormanscron_run_cron_check() {
+  //drupal_page_is_cacheable(FALSE);
+  $_SERVER['REQUEST_METHOD'] = 'POST';
+
+  $cron_run = FALSE;
+
+  // Cron threshold semaphore is used to avoid errors every time the image
+  // callback is displayed when a previous cron is still running.
+  $threshold_semaphore = variable_get('cron_threshold_semaphore', FALSE);
+  if ($threshold_semaphore) {
+    if (REQUEST_TIME - $threshold_semaphore > 3600) {
+      // Either cron has been running for more than an hour or the semaphore
+      // was not reset due to a database error.
+      watchdog('cron', 'Cron has been running for more than an hour and is most likely stuck.', array(), WATCHDOG_ERROR);
 
-    // Delete any messages added during the cron run (and existing prior
-    // messages).
-    drupal_get_messages();
-
-    // Restore any prior messages.
-    if (isset($saved_messages)) {
-      foreach ($saved_messages as $type => $types_messages) {
-        foreach ($types_messages as $message) {
-          drupal_set_message($message, $type);
-        }
-      }
+      // Release the cron threshold semaphore.
+      variable_del('cron_threshold_semaphore');
+    }
+  }
+  else {
+    // Run cron automatically if it has never run or threshold was crossed.
+    $cron_last = variable_get('cron_last', NULL);
+    $cron_threshold = variable_get('cron_safe_threshold', DRUPAL_CRON_DEFAULT_THRESHOLD);
+    if (!isset($cron_last) || (REQUEST_TIME - $cron_last > $cron_threshold) || TRUE) {
+      // Lock cron threshold semaphore.
+      variable_set('cron_threshold_semaphore', REQUEST_TIME);
+      $cron_run = drupal_cron_run();
+      // Release the cron threshold semaphore.
+      variable_del('cron_threshold_semaphore');
     }
   }
+
+  drupal_json(array('cron_run' => $cron_run));
+  exit;
 }
 
 /**
- * Implmentation of hook_menu().
+ * Implementation of hook_form_FORM_ID_alter().
  */
-function poormanscron_menu() {
-  $items = array();
-  $items['admin/settings/poormanscron'] = array(
-    'title' => 'Poormanscron',
-    'description' => 'A module which runs Drupal cron jobs without the cron application.',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('poormanscron_admin_settings'),
-    'access arguments' => array('administer site configuration'),
-    'file' => 'poormanscron.admin.inc',
+function poormanscron_form_system_site_information_settings_alter(&$form, &$form_state) {
+  $form['cron_safe_threshold'] = array(
+    '#type' => 'select',
+    '#title' => t('Automatically run cron'),
+    '#default_value' => variable_get('cron_safe_threshold', DRUPAL_CRON_DEFAULT_THRESHOLD),
+    '#options' => array(0 => t('Never')) + drupal_map_assoc(array(3600, 10800, 21600, 43200, 86400, 604800), 'format_interval'),
+    '#description' => t('When enabled, the site will check whether cron has been run in the configured interval and automatically run it upon the next page request. For more information visit the <a href="@status-report-url">status report page</a>.', array('@status-report-url' => url('admin/reports/status'))),
   );
-  return $items;
+  $form['buttons'] += array('#weight' => 30);
 }
