Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
| Total | |
0 / 0 |
|
100.00% |
0 / 0 |
CRAP | |
72.50% |
87 / 120 |
|
| _scheduler_publish | |
0.00% |
0 / 1 |
0 | |
91.30% |
42 / 46 |
|||
| _scheduler_unpublish | |
0.00% |
0 / 1 |
0 | |
91.11% |
41 / 45 |
|||
| _scheduler_scheduler_nid_list | |
0.00% |
0 / 1 |
0 | |
66.67% |
4 / 6 |
|||
| _scheduler_run_cron | |
0.00% |
0 / 1 |
0 | |
0.00% |
0 / 23 |
|||
| <?php | |
| /** | |
| * @file | |
| * Scheduler cron functions. | |
| * | |
| * This file is included only when running a crontab job or executing the | |
| * lightweight cron via the admin interface. | |
| */ | |
| /** | |
| * Publish scheduled nodes. | |
| * | |
| * @return bool | |
| * TRUE if any node has been published, FALSE otherwise. | |
| */ | |
| function _scheduler_publish() { | |
| $result = FALSE; | |
| // If the time now is greater than the time to publish a node, publish it. | |
| // The INNER join on 'node' and 'users' is just to ensure the nodes are valid. | |
| $query = db_select('scheduler', 's'); | |
| $query->addField('s', 'nid'); | |
| $query->addJoin('INNER', 'node', 'n', 's.nid = n.nid'); | |
| $query->addJoin('INNER', 'users', 'u', 'u.uid = n.uid'); | |
| $query->condition('s.publish_on', 0, '>'); | |
| $query->condition('s.publish_on', REQUEST_TIME, '<='); | |
| $query_result = $query->execute(); | |
| $nids = array(); | |
| while ($node = $query_result->fetchObject()) { | |
| $nids[] = $node->nid; | |
| } | |
| $action = 'publish'; | |
| // Allow other modules to add to the list of nodes to be published. | |
| $nids = array_unique(array_merge($nids, _scheduler_scheduler_nid_list($action))); | |
| // Allow other modules to alter the list of nodes to be published. | |
| drupal_alter('scheduler_nid_list', $nids, $action); | |
| foreach ($nids as $nid) { | |
| $n = node_load($nid); | |
| // Check that other modules allow the action on this node. | |
| if (!_scheduler_allow($n, $action)) { | |
| continue; | |
| } | |
| // Invoke Scheduler API for modules to react before the node is published. | |
| // @todo For D8 move the 'pre' call to here. | |
| // See https://www.drupal.org/node/2311273 | |
| // Update timestamps. | |
| $n->changed = $n->publish_on; | |
| $old_creation_date = $n->created; | |
| if (variable_get('scheduler_publish_touch_' . $n->type, 0) == 1) { | |
| $n->created = $n->publish_on; | |
| } | |
| $create_publishing_revision = variable_get('scheduler_publish_revision_' . $n->type, 0) == 1; | |
| if ($create_publishing_revision) { | |
| $n->revision = TRUE; | |
| // Use a core date format to guarantee a time is included. | |
| $n->log = t('Node published by Scheduler on @now. Previous creation date was @date.', array( | |
| '@now' => format_date(REQUEST_TIME, 'short'), | |
| '@date' => format_date($old_creation_date, 'short'), | |
| )); | |
| } | |
| // Unset publish_on so the node will not get rescheduled by subsequent calls | |
| // to node_save(). Save the value for use when calling Rules. | |
| $publish_on = $n->publish_on; | |
| $n->publish_on = NULL; | |
| // Invoke scheduler API to allow modules to alter the node before it is | |
| // saved. | |
| // @todo For D8, remove this from here. | |
| _scheduler_scheduler_api($n, 'pre_' . $action); | |
| // Use the actions system to publish the node. | |
| watchdog('scheduler', '@type: scheduled publishing of %title.', array('@type' => $n->type, '%title' => $n->title), WATCHDOG_NOTICE, l(t('view'), 'node/' . $n->nid, array('alias' => TRUE))); | |
| $actions = array('node_publish_action', 'node_save_action'); | |
| $context['node'] = $n; | |
| actions_do($actions, $n, $context, NULL, NULL); | |
| // Invoke the event to tell Rules that Scheduler has published this node. | |
| if (module_exists('rules')) { | |
| rules_invoke_event('scheduler_node_has_been_published_event', $n, $publish_on, $n->unpublish_on); | |
| } | |
| // Invoke scheduler API for modules to react after the node is published. | |
| _scheduler_scheduler_api($n, $action); | |
| $result = TRUE; | |
| } | |
| return $result; | |
| } | |
| /** | |
| * Unpublish scheduled nodes. | |
| * | |
| * @return bool | |
| * TRUE is any node has been unpublished, FALSE otherwise. | |
| */ | |
| function _scheduler_unpublish() { | |
| $result = FALSE; | |
| // If the time is greater than the time to unpublish a node, unpublish it. | |
| // The INNER join on 'node' and 'users' is just to ensure the nodes are valid. | |
| $query = db_select('scheduler', 's'); | |
| $query->addField('s', 'nid'); | |
| $query->addJoin('INNER', 'node', 'n', 's.nid = n.nid'); | |
| $query->addJoin('INNER', 'users', 'u', 'u.uid = n.uid'); | |
| $query->condition('s.unpublish_on', 0, '>'); | |
| $query->condition('s.unpublish_on', REQUEST_TIME, '<='); | |
| $query_result = $query->execute(); | |
| $nids = array(); | |
| while ($node = $query_result->fetchObject()) { | |
| $nids[] = $node->nid; | |
| } | |
| $action = 'unpublish'; | |
| // Allow other modules to add to the list of nodes to be unpublished. | |
| $nids = array_unique(array_merge($nids, _scheduler_scheduler_nid_list($action))); | |
| // Allow other modules to alter the list of nodes to be unpublished. | |
| drupal_alter('scheduler_nid_list', $nids, $action); | |
| foreach ($nids as $nid) { | |
| $n = node_load($nid); | |
| // Check that other modules allow the action on this node. | |
| if (!_scheduler_allow($n, $action)) { | |
| continue; | |
| } | |
| // Do not process the node if it has a publish_on time which is in the past, | |
| // as this implies that scheduled publishing has been blocked by one of the | |
| // API functions we provide. Hence unpublishing should be halted too. | |
| if (!empty($n->publish_on) && $n->publish_on <= REQUEST_TIME) { | |
| continue; | |
| } | |
| // Invoke scheduler API for modules to react before the node is unpublished. | |
| // @todo For D8, move the 'pre' call to here. | |
| // See https://www.drupal.org/node/2311273 | |
| // Update timestamps. | |
| $old_change_date = $n->changed; | |
| $n->changed = $n->unpublish_on; | |
| $create_unpublishing_revision = variable_get('scheduler_unpublish_revision_' . $n->type, 0) == 1; | |
| if ($create_unpublishing_revision) { | |
| $n->revision = TRUE; | |
| // Use a core date format to guarantee a time is included. | |
| $n->log = t('Node unpublished by Scheduler on @now. Previous change date was @date.', array( | |
| '@now' => format_date(REQUEST_TIME, 'short'), | |
| '@date' => format_date($old_change_date, 'short'), | |
| )); | |
| } | |
| // Unset unpublish_on so the node will not get rescheduled by subsequent | |
| // calls to node_save(). Save the value for use when calling Rules. | |
| $unpublish_on = $n->unpublish_on; | |
| $n->unpublish_on = NULL; | |
| // Invoke scheduler API to allow modules to alter the node before it is | |
| // saved. | |
| // @todo For D8, remove this from here. | |
| _scheduler_scheduler_api($n, 'pre_' . $action); | |
| // Use the actions system to unpublish the node. | |
| watchdog('scheduler', '@type: scheduled unpublishing of %title.', array('@type' => $n->type, '%title' => $n->title), WATCHDOG_NOTICE, l(t('view'), 'node/' . $n->nid, array('alias' => TRUE))); | |
| $actions = array('node_unpublish_action', 'node_save_action'); | |
| $context['node'] = $n; | |
| actions_do($actions, $n, $context, NULL, NULL); | |
| // Invoke event to tell Rules that Scheduler has unpublished this node. | |
| if (module_exists('rules')) { | |
| rules_invoke_event('scheduler_node_has_been_unpublished_event', $n, $n->publish_on, $unpublish_on); | |
| } | |
| // Invoke scheduler API for modules to react after the node is unpublished. | |
| _scheduler_scheduler_api($n, 'unpublish'); | |
| $result = TRUE; | |
| } | |
| return $result; | |
| } | |
| /** | |
| * Gather node IDs for all nodes that need to be $action'ed. | |
| * | |
| * @param string $action | |
| * The action being performed, either "publish" or "unpublish". | |
| * | |
| * @return array | |
| * An array of node ids. | |
| */ | |
| function _scheduler_scheduler_nid_list($action) { | |
| $nids = array(); | |
| foreach (module_implements('scheduler_nid_list') as $module) { | |
| $function = $module . '_scheduler_nid_list'; | |
| $nids = array_merge($nids, $function($action)); | |
| } | |
| return $nids; | |
| } | |
| /** | |
| * Run the lightweight cron. | |
| * | |
| * The Scheduler part of the processing performed here is the same as in the | |
| * normal Drupal cron run. The difference is that only scheduler_cron() is | |
| * executed, no other modules hook_cron() functions are called. | |
| * | |
| * This function is called from the external crontab job via url /scheduler/cron | |
| * or it can be run interactively from the Scheduler configuration page at | |
| * /admin/config/content/scheduler/cron. | |
| */ | |
| function _scheduler_run_cron() { | |
| $log = variable_get('scheduler_lightweight_log', 1); | |
| if ($log) { | |
| watchdog('scheduler', 'Lightweight cron run activated', array(), WATCHDOG_NOTICE); | |
| } | |
| scheduler_cron(); | |
| if (ob_get_level() > 0) { | |
| $handlers = ob_list_handlers(); | |
| if (isset($handlers[0]) && $handlers[0] == 'default output handler') { | |
| ob_clean(); | |
| } | |
| } | |
| if ($log) { | |
| watchdog('scheduler', 'Lightweight cron run completed', array(), WATCHDOG_NOTICE, l(t('settings'), 'admin/config/content/scheduler/cron')); | |
| } | |
| $menu_item = menu_get_item(); | |
| if ($menu_item['path'] == 'admin/config/content/scheduler/cron') { | |
| // This cron run has been initiated manually from the configuration form. | |
| // Give a message and return something so that an output page is created. | |
| // No output should be returned if running from a crontab job. | |
| if (module_exists('dblog')) { | |
| drupal_set_message(t('Lightweight cron run completed - see <a href="@url">log</a> for details.', array('@url' => url('admin/reports/dblog')))); | |
| } | |
| else { | |
| drupal_set_message(t('Lightweight cron run completed.')); | |
| } | |
| return ' '; | |
| } | |
| // drupal_exit() is the proper controlled way to terminate the request, as | |
| // this will invoke all implementations of hook_exit(). | |
| drupal_exit(); | |
| } |