function scheduler_node_presave in Scheduler 8
Same name and namespace in other branches
- 7 scheduler.module \scheduler_node_presave()
Implements hook_ENTITY_TYPE_presave() for node entities.
4 calls to scheduler_node_presave()
- RemovePublishingDate::doExecute in scheduler_rules_integration/
src/ Plugin/ RulesAction/ RemovePublishingDate.php - Remove the publish_on date from the node.
- RemoveUnpublishingDate::doExecute in scheduler_rules_integration/
src/ Plugin/ RulesAction/ RemoveUnpublishingDate.php - Remove the unpublish_on date from the node.
- SetPublishingDate::doExecute in scheduler_rules_integration/
src/ Plugin/ RulesAction/ SetPublishingDate.php - Set the publish_on date for the node.
- SetUnpublishingDate::doExecute in scheduler_rules_integration/
src/ Plugin/ RulesAction/ SetUnpublishingDate.php - Set the unpublish_on date for the node.
File
- ./
scheduler.module, line 418 - Scheduler publishes and unpublishes nodes on dates specified by the user.
Code
function scheduler_node_presave(EntityInterface $node) {
$config = \Drupal::config('scheduler.settings');
$scheduler_manager = \Drupal::service('scheduler.manager');
$entity = $node->type->entity;
$request_time = \Drupal::time()
->getRequestTime();
$publish_message = FALSE;
$unpublish_message = FALSE;
// If there is no entity object or the class is incorrect then stop here. This
// should not really happen but it has been observed, so better to be safe.
// @see https://www.drupal.org/node/2902512
if (is_null($entity) || !get_class($entity) == 'Drupal\\node\\Entity\\NodeType') {
return;
}
// If this node is being created via Devel Generate then set values for the
// publish_on and unpublish_on dates as specified in the devel_generate form.
if (isset($node->devel_generate)) {
static $publishing_enabled_types;
static $unpublishing_enabled_types;
static $publishing_percent;
static $unpublishing_percent;
static $time_range;
if (!isset($publishing_enabled_types)) {
$publishing_enabled_types = array_keys(_scheduler_get_scheduler_enabled_node_types('publish'));
$unpublishing_enabled_types = array_keys(_scheduler_get_scheduler_enabled_node_types('unpublish'));
// The values may not be set if calling via drush, so default to zero.
$publishing_percent = @$node->devel_generate['scheduler_publishing'] ?: 0;
$unpublishing_percent = @$node->devel_generate['scheduler_unpublishing'] ?: 0;
// Reuse the selected 'node creation' time range for our future date span.
$time_range = $node->devel_generate['time_range'];
}
if ($publishing_percent && in_array($node
->getType(), $publishing_enabled_types)) {
if (rand(1, 100) <= $publishing_percent) {
// Randomly assign a publish_on value in the range starting with the
// created date and up to the selected time range in the future.
$node
->set('publish_on', rand($node->created->value + 1, $request_time + $time_range));
}
}
if ($unpublishing_percent && in_array($node
->getType(), $unpublishing_enabled_types)) {
if (rand(1, 100) <= $unpublishing_percent) {
// Randomly assign an unpublish_on value in the range from the later of
// created date/publish_on date up to the time range in the future.
$node
->set('unpublish_on', rand(max($node->created->value, $node->publish_on->value), $request_time + $time_range));
}
}
}
// If the node type is enabled for scheduled publishing and has a publish_on
// date then check if publishing is allowed and if the content needs to be
// published immediately.
if ($entity
->getThirdPartySetting('scheduler', 'publish_enable', $config
->get('default_publish_enable')) && !empty($node->publish_on->value)) {
// Check that other modules allow the action on this node.
$publication_allowed = $scheduler_manager
->isAllowed($node, 'publish');
// Publish the node immediately if the publication date is in the past.
$publish_immediately = $entity
->getThirdPartySetting('scheduler', 'publish_past_date', $config
->get('default_publish_past_date')) == 'publish';
if ($publication_allowed && $publish_immediately && $node->publish_on->value <= $request_time) {
// Trigger the PRE_PUBLISH_INMEDIATELY event so that modules can react
// before the node has been published.
$event = new SchedulerEvent($node);
$scheduler_manager
->dispatch($event, SchedulerEvents::PRE_PUBLISH_IMMEDIATELY);
$node = $event
->getNode();
// Set the 'changed' timestamp to match what would have been done had this
// content been published via cron.
$node
->setChangedTime($node->publish_on->value);
// If required, set the created date to match published date.
if ($entity
->getThirdPartySetting('scheduler', 'publish_touch', $config
->get('default_publish_touch')) || $node
->getCreatedTime() > $node->publish_on->value && $entity
->getThirdPartySetting('scheduler', 'publish_past_date_created', $config
->get('default_publish_past_date_created'))) {
$node
->setCreatedTime($node->publish_on->value);
}
$node->publish_on->value = NULL;
$node
->setPublished();
// Trigger the PUBLISH_IMMEDIATELY event so that modules can react after
// the node has been published.
$event = new SchedulerEvent($node);
$scheduler_manager
->dispatch($event, SchedulerEvents::PUBLISH_IMMEDIATELY);
$node = $event
->getNode();
}
else {
// Ensure the node is unpublished as it will be published by cron later.
$node
->setUnpublished();
// Only inform the user that the node is scheduled if publication has not
// been prevented by other modules. Those modules have to display a
// message themselves explaining why publication is denied.
$publish_message = $publication_allowed && $entity
->getThirdPartySetting('scheduler', 'show_message_after_update', $config
->get('default_show_message_after_update'));
}
}
if ($entity
->getThirdPartySetting('scheduler', 'unpublish_enable', $config
->get('default_unpublish_enable')) && !empty($node->unpublish_on->value)) {
// Scheduler does not do the same 'immediate' processing for unpublishing.
// However, the api hook should still be called during presave as there may
// be messages to be displayed if the unpublishing will be disallowed later.
$unpublication_allowed = $scheduler_manager
->isAllowed($node, 'unpublish');
$unpublish_message = $unpublication_allowed && $entity
->getThirdPartySetting('scheduler', 'show_message_after_update', $config
->get('default_show_message_after_update'));
}
// Give one message, which will include the publish_on date, the unpublish_on
// date or both dates. Cannot make the title into a link here when the node
// is being created. But the node module gives the link in the next message.
$date_formatter = \Drupal::service('date.formatter');
if ($publish_message && $unpublish_message) {
\Drupal::messenger()
->addMessage(t('%title is scheduled to be published @publish_time and unpublished @unpublish_time.', [
'%title' => $node
->getTitle(),
'@publish_time' => $date_formatter
->format($node->publish_on->value, 'long'),
'@unpublish_time' => $date_formatter
->format($node->unpublish_on->value, 'long'),
]), 'status', FALSE);
}
elseif ($publish_message) {
\Drupal::messenger()
->addMessage(t('%title is scheduled to be published @publish_time.', [
'%title' => $node
->getTitle(),
'@publish_time' => $date_formatter
->format($node->publish_on->value, 'long'),
]), 'status', FALSE);
}
elseif ($unpublish_message) {
\Drupal::messenger()
->addMessage(t('%title is scheduled to be unpublished @unpublish_time.', [
'%title' => $node
->getTitle(),
'@unpublish_time' => $date_formatter
->format($node->unpublish_on->value, 'long'),
]), 'status', FALSE);
}
}