--- scheduler.install 2013-07-27 18:42:28.000000000 +0100 +++ scheduler.install 2013-09-08 18:12:20.000000000 +0100 @@ -60,6 +60,7 @@ function scheduler_uninstall() { $variables[] = "scheduler_publish_touch_" . $type_name; $variables[] = "scheduler_publish_required_" . $type_name; $variables[] = "scheduler_publish_revision_" . $type_name; + $variables[] = "scheduler_publish_past_date_" . $type_name; $variables[] = "scheduler_unpublish_enable_" . $type_name; $variables[] = "scheduler_unpublish_required_" . $type_name; $variables[] = "scheduler_unpublish_revision_" . $type_name; --- scheduler.module 2013-07-27 18:42:28.000000000 +0100 +++ scheduler.module 2013-09-10 09:22:17.000000000 +0100 @@ -234,6 +234,27 @@ function scheduler_form_node_type_form_a '#title' => t('Create a new revision on publishing'), '#default_value' => variable_get('scheduler_publish_revision_' . $form['#node_type']->type, 0), ); + $form['scheduler']['publish']['advanced'] = array( + '#type' => 'fieldset', + '#title' => t('Advanced options'), + '#collapsible' => TRUE, + '#collapsed' => TRUE, + '#states' => array( + 'visible' => array( + ':input[name="scheduler_publish_enable"]' => array('checked' => TRUE), + ), + ), + ); + $form['scheduler']['publish']['advanced']['scheduler_publish_past_date'] = array( + '#type' => 'radios', + '#title' => t('Action to be taken for publication dates in the past'), + '#default_value' => variable_get('scheduler_publish_past_date_' . $form['#node_type']->type, 'error'), + '#options' => array( + 'error' => t('Display an error message - do not allow dates in the past'), + 'publish' => t('Publish the content immediately after saving'), + 'schedule' => t('Schedule the content for publication on the next cron run'), + ), + ); $form['scheduler']['unpublish'] = array( '#type' => 'fieldset', '#title' => t('Unpublishing'), @@ -632,7 +653,7 @@ function scheduler_node_validate($node, if ($publishtime === FALSE) { form_set_error('publish_on', t("The 'publish on' value does not match the expected format of %time", array('%time' => format_date(REQUEST_TIME, 'custom', $date_format)))); } - elseif ($publishtime && $publishtime < REQUEST_TIME) { + elseif ($publishtime && variable_get('scheduler_publish_past_date_' . $node->type, 'error') == 'error' && $publishtime < REQUEST_TIME) { form_set_error('publish_on', t("The 'publish on' date must be in the future")); } } @@ -661,9 +682,14 @@ function scheduler_node_presave($node) { $node->$key = _scheduler_strtotime($node->$key); } } - // Right before we save the node, we need to check if a "publish on" value has been set. - // If it has been set, we want to make sure the node is unpublished since it will be published at a later date - if (isset($node->publish_on) && $node->publish_on != '' && is_numeric($node->publish_on) && $node->publish_on > REQUEST_TIME) { + // Publish the node immediately if the publication date is in the past. + if (variable_get('scheduler_publish_past_date_' . $node->type, 'error') == 'publish' && is_numeric($node->publish_on) && $node->publish_on < REQUEST_TIME) { + $node->publish_on = 0; + $node->status = 1; + } + // Otherwise, if a pubishing date has been set, make sure the node is + // unpublished since it will be published by cron later. + elseif (is_numeric($node->publish_on) && $node->publish_on > 0) { $node->status = 0; $date_format = variable_get('scheduler_date_format', SCHEDULER_DATE_FORMAT); drupal_set_message(t('This post is unpublished and will be published @publish_time.', array('@publish_time' => format_date($node->publish_on, 'custom', $date_format))), 'status', FALSE); @@ -709,6 +735,7 @@ function scheduler_node_type_delete($inf $variables[] = "scheduler_publish_touch_" . $info->type; $variables[] = "scheduler_publish_required_" . $info->type; $variables[] = "scheduler_publish_revision_" . $info->type; + $variables[] = "scheduler_publish_past_date_" . $info->type; $variables[] = "scheduler_unpublish_enable_" . $info->type; $variables[] = "scheduler_unpublish_required_" . $info->type; $variables[] = "scheduler_unpublish_revision_" . $info->type; --- scheduler.test 2013-07-27 18:42:28.000000000 +0100 +++ scheduler.test 2013-09-09 21:36:19.000000000 +0100 @@ -63,4 +63,52 @@ class SchedulerTestCase extends DrupalWe $this->assertNoText($body, t('Node is unpublished')); } } + + /** + * Test the different options for past publication dates. + */ + public function testSchedulerPastDates() { + // Log in. + $this->drupalLogin($this->web_user); + + // Create an unpublished page node. + $node = $this->drupalCreateNode(array('type' => 'page', 'status' => FALSE)); + + // Test the default behavior: an error message should be shown when the user + // enters a publication date that is in the past. + $edit = array( + 'title' => $this->randomName(), + 'publish_on' => format_date(strtotime('-1 day'), 'custom', 'Y-m-d H:i:s'), + ); + $this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save')); + $this->assertRaw(t("The 'publish on' date must be in the future"), 'An error message is shown when the publication date is in the past and the "error" behavior is chosen.'); + + // Test the 'publish' behavior: the node should be published immediately. + variable_set('scheduler_publish_past_date_page', 'publish'); + $this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save')); + $this->assertNoRaw(t("The 'publish on' date must be in the future"), 'No error message is shown when the publication date is in the past and the "publish" behavior is chosen.'); + $this->assertRaw(t('@type %title has been updated.', array('@type' => t('Basic page'), '%title' => check_plain($edit['title']))), 'The node is saved successfully when the publication date is in the past and the "publish" behavior is chosen.'); + + // Reload the changed node and check that it is published. + $node = node_load($node->nid, NULL, TRUE); + $this->assertTrue($node->status, 'The node has been published immediately when the publication date is in the past and the "publish" behavior is chosen.'); + + // Test the 'schedule' behavior: the node should be unpublished and become + // published on the next cron run. + variable_set('scheduler_publish_past_date_page', 'schedule'); + $this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save')); + $this->assertNoRaw(t("The 'publish on' date must be in the future"), 'No error message is shown when the publication date is in the past and the "schedule" behavior is chosen.'); + $this->assertRaw(t('@type %title has been updated.', array('@type' => t('Basic page'), '%title' => check_plain($edit['title']))), 'The node is saved successfully when the publication date is in the past and the "schedule" behavior is chosen.'); + $this->assertRaw(t('This post is unpublished and will be published @publish_time.', array('@publish_time' => $edit['publish_on'])), 'The node is scheduled to be published when the publication date is in the past and the "schedule" behavior is chosen.'); + + // Reload the node and check that it is unpublished but scheduled correctly. + $node = node_load($node->nid, NULL, TRUE); + $this->assertFalse($node->status, 'The node has been unpublished when the publication date is in the past and the "schedule" behavior is chosen.'); + $this->assertEqual(format_date($node->publish_on, 'custom', 'Y-m-d H:i:s'), $edit['publish_on'], 'The node is scheduled for the required date'); + + // Simulate a cron run and check that the node is published. + scheduler_cron(); + $node = node_load($node->nid, NULL, TRUE); + $this->assertTrue($node->status, 'The node with publication date in the past and the "schedule" behavior has now been published by cron.'); + } }