--- scheduler.cron.inc.16 2016-02-08 13:42:13.000000000 +0000 +++ scheduler.cron.inc 2016-02-08 13:47:14.000000000 +0000 @@ -12,6 +12,12 @@ use Drupal\node\Entity\Node; /** + * Declare exception classes. + */ +class SchedulerNodeTypeNotEnabledException extends Exception {} +class SchedulerMissingDateException extends Exception {} + +/** * Publish scheduled nodes. * * @return bool @@ -25,6 +31,8 @@ $query = \Drupal::entityQuery('node') ->condition('publish_on', 0, '>') ->condition('publish_on', REQUEST_TIME, '<='); + // @todo Change this query to exclude nodes which are not enabled for + // publishing. See https://www.drupal.org/node/2659824 $nids = $query->execute(); $action = 'publish'; @@ -36,22 +44,14 @@ \Drupal::moduleHandler()->alter('scheduler_nid_list', $nids, $action); $logger = \Drupal::logger('scheduler'); + // @todo Use dependency injection for the logger when we have written the new + // service for scheduler API. See https://www.drupal.org/node/2651338 $nodes = Node::loadMultiple($nids); foreach ($nodes as $nid => $node) { - $view_link = $node->link(t('View node')); - $nodetype_url = Url::fromRoute('entity.node_type.edit_form', array('node_type' => $node->getType())); - $nodetype_link = \Drupal::l(t('Settings'), $nodetype_url); - $logger_variables = array( - '@type' => $node->getType(), - '%title' => $node->getTitle(), - '%field' => $node->publish_on->label, // @todo this does not work. How to get the label text? - 'link' => $nodetype_link . ' ' . $view_link, - ); - - // The above query and api calls can return nodes of types which are not - // enabled for this scheduler action. Do not process these. + // The API calls could return nodes of types which are not enabled for + // scheduled publishing. Do not process these. if (!$node->type->entity->getThirdPartySetting('scheduler', $action . '_enable', FALSE)) { - $logger->warning('"%title" not published because @type node type is not enabled for Scheduler', $logger_variables); + throw new SchedulerNodeTypeNotEnabledException(sprintf("Node %d '%s' will not be published because node type '%s' is not enabled for scheduled unpublishing", $node->id(), $node->getTitle(), node_get_type_label($node))); continue; } @@ -64,10 +64,12 @@ // @todo For D8 move the 'pre' call to here. // See https://www.drupal.org/node/2311273 - // Ensure we have a valid date to avoid a cron crash if third-party modules - // have altered the node list or node data via the API calls above. + // If an API call has removed the date $node->set('changed', $publish_on) + // would fail, so trap this exception here and give a meaningful message. if (empty($node->publish_on->value)) { - $logger->error('@type "%title" not published because %field field has no value', $logger_variables); + $field_definitions = \Drupal::entityManager()->getFieldDefinitions('node', $node->getType()); + $field = (string)$field_definitions['publish_on']->getLabel(); + throw new SchedulerMissingDateException(sprintf("Node %d '%s' will not be published because field '%s' has no value", $node->id(), $node->getTitle(), $field)); continue; } @@ -98,6 +100,14 @@ _scheduler_scheduler_api($node, 'pre_' . $action); // Log the fact that a scheduled publication is about to take place. + $view_link = $node->link(t('View node')); + $nodetype_url = Url::fromRoute('entity.node_type.edit_form', array('node_type' => $node->getType())); + $nodetype_link = \Drupal::l(node_get_type_label($node) . ' ' . t('settings'), $nodetype_url); + $logger_variables = array( + '@type' => node_get_type_label($node), + '%title' => $node->getTitle(), + 'link' => $nodetype_link . ' ' . $view_link, + ); $logger->notice('@type: scheduled publishing of %title.', $logger_variables); // Use the actions system to publish the node. @@ -131,6 +141,8 @@ $query = \Drupal::entityQuery('node') ->condition('unpublish_on', 0, '>') ->condition('unpublish_on', REQUEST_TIME, '<='); + // @todo Change this query to exclude nodes which are not enabled for + // unpublishing. See https://www.drupal.org/node/2659824 $nids = $query->execute(); $action = 'unpublish'; @@ -142,22 +154,14 @@ \Drupal::moduleHandler()->alter('scheduler_nid_list', $nids, $action); $logger = \Drupal::logger('scheduler'); + // @todo Use dependency injection for the logger when we have written the new + // service for scheduler API. See https://www.drupal.org/node/2651338 $nodes = Node::loadMultiple($nids); foreach ($nodes as $nid => $node) { - $view_link = $node->link(t('View node')); - $nodetype_url = Url::fromRoute('entity.node_type.edit_form', array('node_type' => $node->getType())); - $nodetype_link = \Drupal::l(t('Settings'), $nodetype_url); - $logger_variables = array( - '@type' => $node->getType(), - '%title' => $node->getTitle(), - '%field' => $node->unpublish_on->label, - 'link' => $nodetype_link . ' ' . $view_link, - ); - - // The above query and api calls can return nodes of types which are not - // enabled for this scheduler action. Do not process these. + // The API calls could return nodes of types which are not enabled for + // scheduled unpublishing. Do not process these. if (!$node->type->entity->getThirdPartySetting('scheduler', $action . '_enable', FALSE)) { - $logger->warning('"%title" not unpublished because @type node type is not enabled for Scheduler', $logger_variables); + throw new SchedulerNodeTypeNotEnabledException(sprintf("Node %d '%s' will not be unpublished because node type '%s' is not enabled for scheduled unpublishing", $node->id(), $node->getTitle(), node_get_type_label($node))); continue; } @@ -178,10 +182,12 @@ // @todo For D8, move the 'pre' call to here. // See https://www.drupal.org/node/2311273 - // Ensure we have a valid date to avoid cron crash if third-party modules - // have altered the node list or node data via the API calls above. + // If an API call has removed the date $node->set('changed', $unpublish_on) + // would fail, so trap this exception here and give a meaningful message. if (empty($node->unpublish_on->value)) { - $logger->error('@type "%title" not unpublished because %field field has no value', $logger_variables); + $field_definitions = \Drupal::entityManager()->getFieldDefinitions('node', $node->getType()); + $field = (string)$field_definitions['unpublish_on']->getLabel(); + throw new SchedulerMissingDateException(sprintf("Node %d '%s' will not be unpublished because field '%s' has no value", $node->id(), $node->getTitle(), $field)); continue; } @@ -209,6 +215,14 @@ _scheduler_scheduler_api($node, 'pre_' . $action); // Log the fact that a scheduled unpublication is about to take place. + $view_link = $node->link(t('View node')); + $nodetype_url = Url::fromRoute('entity.node_type.edit_form', array('node_type' => $node->getType())); + $nodetype_link = \Drupal::l(node_get_type_label($node) . ' ' . t('settings'), $nodetype_url); + $logger_variables = array( + '@type' => node_get_type_label($node), + '%title' => $node->getTitle(), + 'link' => $nodetype_link . ' ' . $view_link, + ); $logger->notice('@type: scheduled unpublishing of %title.', $logger_variables); // Use the actions system to publish the node.