You are here

function scheduler_entity_presave in Scheduler 2.x

Implements hook_entity_presave().

4 calls to scheduler_entity_presave()
RemovePublishingDate::doExecute in scheduler_rules_integration/src/Plugin/RulesAction/RemovePublishingDate.php
Remove the publish_on date from the entity.
RemoveUnpublishingDate::doExecute in scheduler_rules_integration/src/Plugin/RulesAction/RemoveUnpublishingDate.php
Remove the unpublish_on date from the entity.
SetPublishingDate::doExecute in scheduler_rules_integration/src/Plugin/RulesAction/SetPublishingDate.php
Set the publish_on date on the entity.
SetUnpublishingDate::doExecute in scheduler_rules_integration/src/Plugin/RulesAction/SetUnpublishingDate.php
Set the unpublish_on date on the entity.

File

./scheduler.module, line 713
Scheduler publishes and unpublishes entities on dates specified by the user.

Code

function scheduler_entity_presave(EntityInterface $entity) {
  $config = \Drupal::config('scheduler.settings');
  $scheduler_manager = \Drupal::service('scheduler.manager');
  $request_time = \Drupal::time()
    ->getRequestTime();
  $publishing_enabled_types = $scheduler_manager
    ->getEnabledTypes($entity
    ->getEntityTypeId(), 'publish');
  $unpublishing_enabled_types = $scheduler_manager
    ->getEnabledTypes($entity
    ->getEntityTypeId(), 'unpublish');
  $publishing_enabled = in_array($entity
    ->bundle(), $publishing_enabled_types);
  $unpublishing_enabled = in_array($entity
    ->bundle(), $unpublishing_enabled_types);
  if (!$publishing_enabled && !$unpublishing_enabled) {

    // Neither scheduled publishing nor unpublishing are enabled for this
    // specific bundle/type, so end here.
    return;
  }

  // If this entity 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($entity->devel_generate)) {
    static $publishing_percent;
    static $unpublishing_percent;
    static $time_range;
    if (!isset($publishing_percent)) {

      // The values may not be set if calling via drush, so default to zero.
      $publishing_percent = @$entity->devel_generate['scheduler_publishing'] ?: 0;
      $unpublishing_percent = @$entity->devel_generate['scheduler_unpublishing'] ?: 0;

      // Reuse the selected 'creation' time range for our future date span.
      $time_range = $entity->devel_generate['time_range'];
    }
    if ($publishing_percent && $publishing_enabled) {
      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.
        $entity
          ->set('publish_on', rand($entity->created->value + 1, $request_time + $time_range));
      }
    }
    if ($unpublishing_percent && $unpublishing_enabled) {
      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.
        $entity
          ->set('unpublish_on', rand(max($entity->created->value, $entity->publish_on->value), $request_time + $time_range));
      }
    }
  }
  $publish_message = FALSE;
  $unpublish_message = FALSE;

  // If the entity 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 ($publishing_enabled && !empty($entity->publish_on->value)) {

    // Check that other modules allow the action on this entity.
    $publication_allowed = $scheduler_manager
      ->isAllowed($entity, 'publish');

    // Publish the entity immediately if the publication date is in the past.
    $publish_immediately = $scheduler_manager
      ->getThirdPartySetting($entity, 'publish_past_date', $config
      ->get('default_publish_past_date')) == 'publish';
    if ($publication_allowed && $publish_immediately && $entity->publish_on->value <= $request_time) {

      // Trigger the PRE_PUBLISH_IMMEDIATELY event so that modules can react
      // before the entity has been published.
      $scheduler_manager
        ->dispatchSchedulerEvent($entity, 'PRE_PUBLISH_IMMEDIATELY');

      // Set the 'changed' timestamp to match what would have been done had this
      // content been published via cron.
      $entity
        ->setChangedTime($entity->publish_on->value);

      // If required, set the created date to match published date.
      if ($scheduler_manager
        ->getThirdPartySetting($entity, 'publish_touch', $config
        ->get('default_publish_touch')) || $entity
        ->getCreatedTime() > $entity->publish_on->value && $scheduler_manager
        ->getThirdPartySetting($entity, 'publish_past_date_created', $config
        ->get('default_publish_past_date_created'))) {
        $entity
          ->setCreatedTime($entity->publish_on->value);
      }
      $entity->publish_on->value = NULL;
      $entity
        ->setPublished();

      // Trigger the PUBLISH_IMMEDIATELY event so that modules can react after
      // the entity has been published.
      $scheduler_manager
        ->dispatchSchedulerEvent($entity, 'PUBLISH_IMMEDIATELY');
    }
    else {

      // Ensure the entity is unpublished as it will be published by cron later.
      $entity
        ->setUnpublished();

      // Only inform the user that the entity 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 && $scheduler_manager
        ->getThirdPartySetting($entity, 'show_message_after_update', $config
        ->get('default_show_message_after_update'));
    }
  }

  // Entity has a publish_on date.
  if ($unpublishing_enabled && !empty($entity->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($entity, 'unpublish');
    $unpublish_message = $unpublication_allowed && $scheduler_manager
      ->getThirdPartySetting($entity, '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 entity
  // is being created. But core provides the link in the subsequent 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' => $entity
        ->label(),
      '@publish_time' => $date_formatter
        ->format($entity->publish_on->value, 'long'),
      '@unpublish_time' => $date_formatter
        ->format($entity->unpublish_on->value, 'long'),
    ]), 'status', FALSE);
  }
  elseif ($publish_message) {
    \Drupal::messenger()
      ->addMessage(t('%title is scheduled to be published @publish_time.', [
      '%title' => $entity
        ->label(),
      '@publish_time' => $date_formatter
        ->format($entity->publish_on->value, 'long'),
    ]), 'status', FALSE);
  }
  elseif ($unpublish_message) {
    \Drupal::messenger()
      ->addMessage(t('%title is scheduled to be unpublished @unpublish_time.', [
      '%title' => $entity
        ->label(),
      '@unpublish_time' => $date_formatter
        ->format($entity->unpublish_on->value, 'long'),
    ]), 'status', FALSE);
  }
}