Loading modules/cps_scheduler/cps_scheduler.api.php 0 → 100644 +35 −0 Original line number Diff line number Diff line <?php /** * @file * Hooks provided by the CPS scheduler module. */ /** * @addtogroup hooks * @{ */ /** * Alter the errors when checking if a changeset can be scheduled. * * @param $errors * An array of errors keyed by type * * @param $entities * The list of tracked entitites */ function hook_cps_scheduler_not_allowed_alter(&$errors, $entities) { unset($errors['entity_type:taxonomy_term']); foreach ($entities as $entity_type => $entities) { foreach ($entities as $entity_id) { if ($entity_type == 'node' && $entity_id == 1) { $errors[$entity_type . ':' . $entity_id] = FALSE; } } } } /** * @} End of "addtogroup hooks". */ modules/cps_scheduler/cps_scheduler.drush.inc 0 → 100644 +25 −0 Original line number Diff line number Diff line <?php /** * @file * CPS Scheduler drush commands. */ /** * Implements hook_drush_command(). */ function cps_scheduler_drush_command() { $items['cps-scheduler-run'] = array( 'description' => t('Run scheduled publishing.'), 'aliases' => array('cpssr'), ); return $items; } /** * Drush command callback */ function drush_cps_scheduler_run() { _cps_scheduler_scheduled_publish(); } modules/cps_scheduler/cps_scheduler.info 0 → 100644 +5 −0 Original line number Diff line number Diff line name = CPS Scheduler description = This module allows a CPS site version to be published on specified date and time. core = 7.x dependencies[] = cps modules/cps_scheduler/cps_scheduler.install 0 → 100644 +25 −0 Original line number Diff line number Diff line <?php function cps_scheduler_schema() { $schema['cps_scheduler'] = [ 'description' => 'CPS Scheduler table.', 'fields' => [ 'changeset_id' => [ 'description' => 'A machine name identifying the changeset.', 'type' => 'varchar', 'length' => 64, 'not null' => TRUE, 'default' => '', ], 'publish_on' => [ 'description' => 'The UNIX UTC timestamp when to publish', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, ], ], 'primary key' => ['changeset_id'], ]; return $schema; } modules/cps_scheduler/cps_scheduler.module 0 → 100644 +444 −0 Original line number Diff line number Diff line <?php define('CPS_SCHEDULER_DATE_FORMAT', 'Y-m-d H:i'); /** * Implements hook_menu(). */ function cps_scheduler_menu() { $items = []; $items['admin/structure/changesets/scheduled'] = array( 'title' => 'Scheduled', 'page callback' => 'cps_changeset_list_page', 'page arguments' => array('scheduled_site_versions'), 'file' => 'includes/admin.inc', 'file path' => drupal_get_path('module', 'cps'), 'access arguments' => array('administer changesets'), 'weight' => 20, 'type' => MENU_LOCAL_TASK, ); return $items; } /** * Implements hook_permission(). */ function cps_scheduler_permission() { return array( 'schedule cps changesets' => array( 'title' => t('Schedule CPS changesets to be published on specified date and time'), ), ); } /** * Implements hook_cps_changeset_state_types_alter(). */ function cps_scheduler_cps_changeset_states_alter(&$states) { // Add a state type for changesets that are scheduled to be published. $states['scheduled'] = array( 'label' => t('Scheduled'), 'weight' => 0, 'type' => 'closed', ); } /** * Implements hook_cps_transitions(). * * Add "schedule" and "cancel scheduling" transitions. */ function cps_scheduler_cps_transitions() { return [ 'schedule' => [ 'label' => t('Schedule'), 'valid states' => ['unpublished'], 'state' => 'scheduled', 'menu' => [ 'title' => t('Schedule'), 'weight' => -1, ], 'access callback' => [ 'cps_scheduler_schedule_access_callback' => [], ], 'transition callback' => [ 'cps_scheduler_schedule_transition_callback' => [], ], 'message' => [ 'subject' => t('@site-name: "@site-version-name" submitted for schedule'), 'body' => '<p>@user-name submitted a site version for schedule.</p><blockquote>!message</blockquote><hr><p>!site-version</p>', ], 'transition message' => t('This site version will be submitted for schedule.'), 'transition success' => t('The site version has been submitted for schedule.'), ], 'cancel_scheduling' => [ 'label' => t('Cancel scheduling'), 'valid states' => ['scheduled'], 'state' => 'unpublished', 'menu' => [ 'title' => t('Cancel scheduling'), 'weight' => -1, ], 'access callback' => [ 'cps_transition_default_transition_user_access_callback' => ['schedule cps changesets'], ], 'transition callback' => [ 'cps_scheduler_cancel_schedule_transition_callback' => [], ], 'message' => [ 'subject' => t('@site-name: "@site-version-name" submitted for remove from scheduling'), 'body' => '<p>@user-name submitted a site version for unscheduling.</p><blockquote>!message</blockquote><hr><p>!site-version</p>', ], 'transition message' => t('This site version will be submitted for remove from scheduling.'), 'transition success' => t('The site version has been submitted for remove from scheduling.'), ], ]; } /** * Schedule transition access callback * * @param \CPSChangeset $changeset * The changeset * * @param string $transition * The transition name * * @param array $transition_info * The transition info * @param null $account * The user account * * @return bool */ function cps_scheduler_schedule_access_callback(CPSChangeset $changeset, $transition, $transition_info, $account = NULL) { if (user_access('schedule cps changesets')) { return _cps_scheduler_can_be_scheduled($changeset); } return FALSE; } /** * Implements hook_form_FORM_ID_alter(). * * Add publish settings on transition form. */ function cps_scheduler_form_cps_transition_transition_form_alter(&$form, &$form_state, $form_id) { if ($form_state['transition'] == 'schedule') { $changeset = $form_state['changeset']; $publish_on = db_select('cps_scheduler', 'cs') ->fields('cs', ['publish_on']) ->condition('changeset_id', $changeset->changeset_id) ->execute() ->fetchField(); $form['scheduler_settings'] = [ '#type' => 'fieldset', '#title' => t('Scheduling options'), '#collapsible' => TRUE, '#collapsed' => FALSE, '#weight' => -100, ]; $form['scheduler_settings']['publish_on'] = [ '#type' => 'textfield', '#title' => t('Publish on'), '#maxlength' => 30, '#required' => FALSE, '#default_value' => !empty($publish_on) ? date(CPS_SCHEDULER_DATE_FORMAT, $publish_on) : '', '#description' => t('Leave the date blank for no scheduled publishing.'), '#disabled' => $changeset->status == 'scheduled', ]; if (module_exists('date_popup')) { // Make this a popup calendar widget. $form['scheduler_settings']['publish_on']['#type'] = 'date_popup'; $form['scheduler_settings']['publish_on']['#date_format'] = CPS_SCHEDULER_DATE_FORMAT; $form['scheduler_settings']['publish_on']['#date_year_range'] = '0:+10'; $form['scheduler_settings']['publish_on']['#date_increment'] = 1; unset($form['scheduler_settings']['publish_on']['#maxlength']); } $form['#validate'][] = 'cps_scheduler_form_cps_transition_transition_form_validate'; array_unshift($form['#submit'], 'cps_scheduler_form_cps_transition_transition_form_submit'); } } /** * CPS Scheduler form validate handler */ function cps_scheduler_form_cps_transition_transition_form_validate($form, $form_state) { if (empty($form_state['values']['publish_on'])) { form_set_error('publish_on', t("The 'publish on' date cannot be empty")); } if (strtotime($form_state['values']['publish_on']) <= REQUEST_TIME) { form_set_error('publish_on', t("The 'publish on' date must be in the future")); } } /** * CPS Scheduler form submit handler */ function cps_scheduler_form_cps_transition_transition_form_submit($form, &$form_state) { // Set publish on attribute to changeset to use it on transition callback. if (!empty($form_state['values']['publish_on'])) { $form_state['changeset']->publish_on = $form_state['values']['publish_on']; } } /** * Schedule transition callback * * Add changeset to scheduling and set its status to "scheduled". * * @param \CPSChangeset $changeset * The changeset * * @param string $transition * The transition name * * @param array $transition_info * The transition info * * @return bool * @throws \InvalidMergeQueryException */ function cps_scheduler_schedule_transition_callback(CPSChangeset $changeset, $transition, $transition_info) { if (!empty($changeset->publish_on)) { $publish_on = strtotime($changeset->publish_on); $message = t('Scheduled for %date', ['%date' => date(CPS_SCHEDULER_DATE_FORMAT, $publish_on)]); db_merge('cps_scheduler') ->key(['changeset_id' => $changeset->changeset_id]) ->fields(['publish_on' => $publish_on]) ->execute(); $changeset->setStatus($transition_info['state'], $message); $changeset->save(); return TRUE; } return FALSE; } /** * Cancel scheduling transition callback * * Delete the scheduling and revert the changeset status to unpublished. * * @param \CPSChangeset $changeset * The changeset * * @param string $transition * The transition name * * @param array $transition_info * The transition info * * @return bool */ function cps_scheduler_cancel_schedule_transition_callback(CPSChangeset $changeset, $transition, $transition_info) { db_delete('cps_scheduler') ->condition('changeset_id', $changeset->changeset_id) ->execute(); $message = t('Site version removed form scheduling.'); $changeset->setStatus($transition_info['state'], $message); $changeset->save(); return TRUE; } /** * Implements hook_cps_changeset_operations_alter() * * For scheduled changeset only view, status and cancel scheduling operations * are available * * @param $operations * @param $changeset */ function cps_scheduler_cps_changeset_operations_alter(&$operations, $changeset) { $allowed_states = ['site', 'view', 'cancel_scheduling']; if ($changeset->status == 'scheduled') { foreach (element_children($operations) as $state) { if (!in_array($state, $allowed_states)) { $operations[$state]['#access'] = FALSE; } } } } /** * Implements hook_cps_changeset_access_alter(). * * For scheduled changeset only view and cancel scheduling actions are available */ function cps_scheduler_cps_changeset_access_alter(&$access, $op, $changeset, $account) { if ($changeset && $changeset->status == 'scheduled') { // Allow bulk copy from a scheduled changeset. if ($op == 'update' && arg(4) == 'bulk' && arg(5) == 'copy') { return $access; } if (!in_array($op, ['view', 'cancel_scheduling'])) { $access = FALSE; } } return $access; } /** * Implements hook_cron(). */ function cps_scheduler_cron() { _cps_scheduler_scheduled_publish(); } /** * Get all the scheduled site versions and publish them. */ function _cps_scheduler_scheduled_publish() { $changeset_ids = db_select('cps_scheduler', 'cs') ->fields('cs', ['changeset_id', 'changeset_id']) ->condition('cs.publish_on', 0, '>') ->condition('cs.publish_on', REQUEST_TIME, '<=') ->execute() ->fetchAllKeyed(); if (!empty($changeset_ids)) { foreach ($changeset_ids as $changeset_id) { $changeset = cps_changeset_load($changeset_id); // If changeset_id is not valid abort the publish operation. if (!$changeset) { watchdog('cps_scheduler', t('There was an error loading %changeset.'), ['%changeset' => $changeset_id], WATCHDOG_ERROR); break; } // If publish process is locked, log the error and stop the flow. $lock = cps_acquire_processing_lock(); if (!$lock) { watchdog('cps_scheduler', t('CPS is processing another site version, please try again later.'), [], WATCHDOG_ERROR); break; } // Change the changeset status to publish it: only open changeset could be // published. $changeset->status = 'unpublished'; if (cps_publish_changeset($changeset)) { // Remove changeset's scheduling. db_delete('cps_scheduler') ->condition('changeset_id', $changeset_id) ->execute(); cps_release_processing_lock(); watchdog('cps_scheduler', t('%changeset successfully published.'), ['%changeset' => $changeset_id], WATCHDOG_INFO); } else { watchdog('cps_scheduler', t('There was an error processing %changeset.'), ['%changeset' => $changeset_id], WATCHDOG_ERROR); cps_release_processing_lock(); } } } } /** * Implements hook_form_FORM_ID_alter(). */ function cps_scheduler_form_cps_changeset_preview_form_alter(&$form, &$form_state) { $changeset_id = cps_get_current_changeset(TRUE); if ($changeset_id != CPS_PUBLISHED_CHANGESET) { // Add publish and schedule/unschedule links. $changeset = cps_changeset_load($changeset_id); if ($changeset->status == 'scheduled') { $unschedule_path = 'admin/structure/changesets/' . $changeset_id . '/transition-cancel_scheduling'; $unschedule_text = t('Unschedule Site Version'); $form['unschedule'] = [ '#markup' => l( $unschedule_text, $unschedule_path, ['attributes' => ['title' => $unschedule_text, 'class' => ['cps-changeset--cancel-scheduling']]] ), '#access' => drupal_valid_path($unschedule_path), ]; } else { $publish_text = t('Publish Site Version'); $publish_path = 'admin/structure/changesets/' . $changeset_id . '/publish'; $schedule_text = t('Schedule Site Version'); $schedule_path = 'admin/structure/changesets/' . $changeset_id . '/transition-schedule'; $form['publish'] = [ '#markup' => l( $publish_text, $publish_path, ['attributes' => ['title' => $publish_text, 'class' => ['cps-changeset--publish']]] ), '#access' => drupal_valid_path($publish_path), ]; $form['schedule'] = [ '#markup' => l( $schedule_text, $schedule_path, ['attributes' => ['title' => $schedule_text, 'class' => ['cps-changeset--schedule']]] ), '#access' => drupal_valid_path($schedule_path), ]; } } } /** * Implements hook_preprocess_page(). */ function cps_scheduler_preprocess_page(&$variables) { $path_to_module = drupal_get_path('module', 'cps_scheduler'); drupal_add_css($path_to_module . '/css/cps_scheduler.css'); } /** * Implements hook_views_api(). */ function cps_scheduler_views_api() { return array( 'path' => drupal_get_path('module', 'cps_scheduler') . '/views', 'api' => 3, ); } /** * Check if changeset has changed entities that are not allowed for scheduling. * * @param $changeset_id * The changeset ID * * @return array|bool */ function _cps_scheduler_can_be_scheduled($changeset) { $errors = []; $entities = cps_get_tracked_entities($changeset->changeset_id); $not_allowed = variable_get('cps_scheduler_disallowed_entity_types', []); foreach ($not_allowed as $entity_type) { if (isset($entities[$entity_type])) { $errors['entity_type:' . $entity_type] = FALSE; } } drupal_alter('cps_scheduler_not_allowed', $errors, $entities); return count($errors) == 0; } Loading
modules/cps_scheduler/cps_scheduler.api.php 0 → 100644 +35 −0 Original line number Diff line number Diff line <?php /** * @file * Hooks provided by the CPS scheduler module. */ /** * @addtogroup hooks * @{ */ /** * Alter the errors when checking if a changeset can be scheduled. * * @param $errors * An array of errors keyed by type * * @param $entities * The list of tracked entitites */ function hook_cps_scheduler_not_allowed_alter(&$errors, $entities) { unset($errors['entity_type:taxonomy_term']); foreach ($entities as $entity_type => $entities) { foreach ($entities as $entity_id) { if ($entity_type == 'node' && $entity_id == 1) { $errors[$entity_type . ':' . $entity_id] = FALSE; } } } } /** * @} End of "addtogroup hooks". */
modules/cps_scheduler/cps_scheduler.drush.inc 0 → 100644 +25 −0 Original line number Diff line number Diff line <?php /** * @file * CPS Scheduler drush commands. */ /** * Implements hook_drush_command(). */ function cps_scheduler_drush_command() { $items['cps-scheduler-run'] = array( 'description' => t('Run scheduled publishing.'), 'aliases' => array('cpssr'), ); return $items; } /** * Drush command callback */ function drush_cps_scheduler_run() { _cps_scheduler_scheduled_publish(); }
modules/cps_scheduler/cps_scheduler.info 0 → 100644 +5 −0 Original line number Diff line number Diff line name = CPS Scheduler description = This module allows a CPS site version to be published on specified date and time. core = 7.x dependencies[] = cps
modules/cps_scheduler/cps_scheduler.install 0 → 100644 +25 −0 Original line number Diff line number Diff line <?php function cps_scheduler_schema() { $schema['cps_scheduler'] = [ 'description' => 'CPS Scheduler table.', 'fields' => [ 'changeset_id' => [ 'description' => 'A machine name identifying the changeset.', 'type' => 'varchar', 'length' => 64, 'not null' => TRUE, 'default' => '', ], 'publish_on' => [ 'description' => 'The UNIX UTC timestamp when to publish', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, ], ], 'primary key' => ['changeset_id'], ]; return $schema; }
modules/cps_scheduler/cps_scheduler.module 0 → 100644 +444 −0 Original line number Diff line number Diff line <?php define('CPS_SCHEDULER_DATE_FORMAT', 'Y-m-d H:i'); /** * Implements hook_menu(). */ function cps_scheduler_menu() { $items = []; $items['admin/structure/changesets/scheduled'] = array( 'title' => 'Scheduled', 'page callback' => 'cps_changeset_list_page', 'page arguments' => array('scheduled_site_versions'), 'file' => 'includes/admin.inc', 'file path' => drupal_get_path('module', 'cps'), 'access arguments' => array('administer changesets'), 'weight' => 20, 'type' => MENU_LOCAL_TASK, ); return $items; } /** * Implements hook_permission(). */ function cps_scheduler_permission() { return array( 'schedule cps changesets' => array( 'title' => t('Schedule CPS changesets to be published on specified date and time'), ), ); } /** * Implements hook_cps_changeset_state_types_alter(). */ function cps_scheduler_cps_changeset_states_alter(&$states) { // Add a state type for changesets that are scheduled to be published. $states['scheduled'] = array( 'label' => t('Scheduled'), 'weight' => 0, 'type' => 'closed', ); } /** * Implements hook_cps_transitions(). * * Add "schedule" and "cancel scheduling" transitions. */ function cps_scheduler_cps_transitions() { return [ 'schedule' => [ 'label' => t('Schedule'), 'valid states' => ['unpublished'], 'state' => 'scheduled', 'menu' => [ 'title' => t('Schedule'), 'weight' => -1, ], 'access callback' => [ 'cps_scheduler_schedule_access_callback' => [], ], 'transition callback' => [ 'cps_scheduler_schedule_transition_callback' => [], ], 'message' => [ 'subject' => t('@site-name: "@site-version-name" submitted for schedule'), 'body' => '<p>@user-name submitted a site version for schedule.</p><blockquote>!message</blockquote><hr><p>!site-version</p>', ], 'transition message' => t('This site version will be submitted for schedule.'), 'transition success' => t('The site version has been submitted for schedule.'), ], 'cancel_scheduling' => [ 'label' => t('Cancel scheduling'), 'valid states' => ['scheduled'], 'state' => 'unpublished', 'menu' => [ 'title' => t('Cancel scheduling'), 'weight' => -1, ], 'access callback' => [ 'cps_transition_default_transition_user_access_callback' => ['schedule cps changesets'], ], 'transition callback' => [ 'cps_scheduler_cancel_schedule_transition_callback' => [], ], 'message' => [ 'subject' => t('@site-name: "@site-version-name" submitted for remove from scheduling'), 'body' => '<p>@user-name submitted a site version for unscheduling.</p><blockquote>!message</blockquote><hr><p>!site-version</p>', ], 'transition message' => t('This site version will be submitted for remove from scheduling.'), 'transition success' => t('The site version has been submitted for remove from scheduling.'), ], ]; } /** * Schedule transition access callback * * @param \CPSChangeset $changeset * The changeset * * @param string $transition * The transition name * * @param array $transition_info * The transition info * @param null $account * The user account * * @return bool */ function cps_scheduler_schedule_access_callback(CPSChangeset $changeset, $transition, $transition_info, $account = NULL) { if (user_access('schedule cps changesets')) { return _cps_scheduler_can_be_scheduled($changeset); } return FALSE; } /** * Implements hook_form_FORM_ID_alter(). * * Add publish settings on transition form. */ function cps_scheduler_form_cps_transition_transition_form_alter(&$form, &$form_state, $form_id) { if ($form_state['transition'] == 'schedule') { $changeset = $form_state['changeset']; $publish_on = db_select('cps_scheduler', 'cs') ->fields('cs', ['publish_on']) ->condition('changeset_id', $changeset->changeset_id) ->execute() ->fetchField(); $form['scheduler_settings'] = [ '#type' => 'fieldset', '#title' => t('Scheduling options'), '#collapsible' => TRUE, '#collapsed' => FALSE, '#weight' => -100, ]; $form['scheduler_settings']['publish_on'] = [ '#type' => 'textfield', '#title' => t('Publish on'), '#maxlength' => 30, '#required' => FALSE, '#default_value' => !empty($publish_on) ? date(CPS_SCHEDULER_DATE_FORMAT, $publish_on) : '', '#description' => t('Leave the date blank for no scheduled publishing.'), '#disabled' => $changeset->status == 'scheduled', ]; if (module_exists('date_popup')) { // Make this a popup calendar widget. $form['scheduler_settings']['publish_on']['#type'] = 'date_popup'; $form['scheduler_settings']['publish_on']['#date_format'] = CPS_SCHEDULER_DATE_FORMAT; $form['scheduler_settings']['publish_on']['#date_year_range'] = '0:+10'; $form['scheduler_settings']['publish_on']['#date_increment'] = 1; unset($form['scheduler_settings']['publish_on']['#maxlength']); } $form['#validate'][] = 'cps_scheduler_form_cps_transition_transition_form_validate'; array_unshift($form['#submit'], 'cps_scheduler_form_cps_transition_transition_form_submit'); } } /** * CPS Scheduler form validate handler */ function cps_scheduler_form_cps_transition_transition_form_validate($form, $form_state) { if (empty($form_state['values']['publish_on'])) { form_set_error('publish_on', t("The 'publish on' date cannot be empty")); } if (strtotime($form_state['values']['publish_on']) <= REQUEST_TIME) { form_set_error('publish_on', t("The 'publish on' date must be in the future")); } } /** * CPS Scheduler form submit handler */ function cps_scheduler_form_cps_transition_transition_form_submit($form, &$form_state) { // Set publish on attribute to changeset to use it on transition callback. if (!empty($form_state['values']['publish_on'])) { $form_state['changeset']->publish_on = $form_state['values']['publish_on']; } } /** * Schedule transition callback * * Add changeset to scheduling and set its status to "scheduled". * * @param \CPSChangeset $changeset * The changeset * * @param string $transition * The transition name * * @param array $transition_info * The transition info * * @return bool * @throws \InvalidMergeQueryException */ function cps_scheduler_schedule_transition_callback(CPSChangeset $changeset, $transition, $transition_info) { if (!empty($changeset->publish_on)) { $publish_on = strtotime($changeset->publish_on); $message = t('Scheduled for %date', ['%date' => date(CPS_SCHEDULER_DATE_FORMAT, $publish_on)]); db_merge('cps_scheduler') ->key(['changeset_id' => $changeset->changeset_id]) ->fields(['publish_on' => $publish_on]) ->execute(); $changeset->setStatus($transition_info['state'], $message); $changeset->save(); return TRUE; } return FALSE; } /** * Cancel scheduling transition callback * * Delete the scheduling and revert the changeset status to unpublished. * * @param \CPSChangeset $changeset * The changeset * * @param string $transition * The transition name * * @param array $transition_info * The transition info * * @return bool */ function cps_scheduler_cancel_schedule_transition_callback(CPSChangeset $changeset, $transition, $transition_info) { db_delete('cps_scheduler') ->condition('changeset_id', $changeset->changeset_id) ->execute(); $message = t('Site version removed form scheduling.'); $changeset->setStatus($transition_info['state'], $message); $changeset->save(); return TRUE; } /** * Implements hook_cps_changeset_operations_alter() * * For scheduled changeset only view, status and cancel scheduling operations * are available * * @param $operations * @param $changeset */ function cps_scheduler_cps_changeset_operations_alter(&$operations, $changeset) { $allowed_states = ['site', 'view', 'cancel_scheduling']; if ($changeset->status == 'scheduled') { foreach (element_children($operations) as $state) { if (!in_array($state, $allowed_states)) { $operations[$state]['#access'] = FALSE; } } } } /** * Implements hook_cps_changeset_access_alter(). * * For scheduled changeset only view and cancel scheduling actions are available */ function cps_scheduler_cps_changeset_access_alter(&$access, $op, $changeset, $account) { if ($changeset && $changeset->status == 'scheduled') { // Allow bulk copy from a scheduled changeset. if ($op == 'update' && arg(4) == 'bulk' && arg(5) == 'copy') { return $access; } if (!in_array($op, ['view', 'cancel_scheduling'])) { $access = FALSE; } } return $access; } /** * Implements hook_cron(). */ function cps_scheduler_cron() { _cps_scheduler_scheduled_publish(); } /** * Get all the scheduled site versions and publish them. */ function _cps_scheduler_scheduled_publish() { $changeset_ids = db_select('cps_scheduler', 'cs') ->fields('cs', ['changeset_id', 'changeset_id']) ->condition('cs.publish_on', 0, '>') ->condition('cs.publish_on', REQUEST_TIME, '<=') ->execute() ->fetchAllKeyed(); if (!empty($changeset_ids)) { foreach ($changeset_ids as $changeset_id) { $changeset = cps_changeset_load($changeset_id); // If changeset_id is not valid abort the publish operation. if (!$changeset) { watchdog('cps_scheduler', t('There was an error loading %changeset.'), ['%changeset' => $changeset_id], WATCHDOG_ERROR); break; } // If publish process is locked, log the error and stop the flow. $lock = cps_acquire_processing_lock(); if (!$lock) { watchdog('cps_scheduler', t('CPS is processing another site version, please try again later.'), [], WATCHDOG_ERROR); break; } // Change the changeset status to publish it: only open changeset could be // published. $changeset->status = 'unpublished'; if (cps_publish_changeset($changeset)) { // Remove changeset's scheduling. db_delete('cps_scheduler') ->condition('changeset_id', $changeset_id) ->execute(); cps_release_processing_lock(); watchdog('cps_scheduler', t('%changeset successfully published.'), ['%changeset' => $changeset_id], WATCHDOG_INFO); } else { watchdog('cps_scheduler', t('There was an error processing %changeset.'), ['%changeset' => $changeset_id], WATCHDOG_ERROR); cps_release_processing_lock(); } } } } /** * Implements hook_form_FORM_ID_alter(). */ function cps_scheduler_form_cps_changeset_preview_form_alter(&$form, &$form_state) { $changeset_id = cps_get_current_changeset(TRUE); if ($changeset_id != CPS_PUBLISHED_CHANGESET) { // Add publish and schedule/unschedule links. $changeset = cps_changeset_load($changeset_id); if ($changeset->status == 'scheduled') { $unschedule_path = 'admin/structure/changesets/' . $changeset_id . '/transition-cancel_scheduling'; $unschedule_text = t('Unschedule Site Version'); $form['unschedule'] = [ '#markup' => l( $unschedule_text, $unschedule_path, ['attributes' => ['title' => $unschedule_text, 'class' => ['cps-changeset--cancel-scheduling']]] ), '#access' => drupal_valid_path($unschedule_path), ]; } else { $publish_text = t('Publish Site Version'); $publish_path = 'admin/structure/changesets/' . $changeset_id . '/publish'; $schedule_text = t('Schedule Site Version'); $schedule_path = 'admin/structure/changesets/' . $changeset_id . '/transition-schedule'; $form['publish'] = [ '#markup' => l( $publish_text, $publish_path, ['attributes' => ['title' => $publish_text, 'class' => ['cps-changeset--publish']]] ), '#access' => drupal_valid_path($publish_path), ]; $form['schedule'] = [ '#markup' => l( $schedule_text, $schedule_path, ['attributes' => ['title' => $schedule_text, 'class' => ['cps-changeset--schedule']]] ), '#access' => drupal_valid_path($schedule_path), ]; } } } /** * Implements hook_preprocess_page(). */ function cps_scheduler_preprocess_page(&$variables) { $path_to_module = drupal_get_path('module', 'cps_scheduler'); drupal_add_css($path_to_module . '/css/cps_scheduler.css'); } /** * Implements hook_views_api(). */ function cps_scheduler_views_api() { return array( 'path' => drupal_get_path('module', 'cps_scheduler') . '/views', 'api' => 3, ); } /** * Check if changeset has changed entities that are not allowed for scheduling. * * @param $changeset_id * The changeset ID * * @return array|bool */ function _cps_scheduler_can_be_scheduled($changeset) { $errors = []; $entities = cps_get_tracked_entities($changeset->changeset_id); $not_allowed = variable_get('cps_scheduler_disallowed_entity_types', []); foreach ($not_allowed as $entity_type) { if (isset($entities[$entity_type])) { $errors['entity_type:' . $entity_type] = FALSE; } } drupal_alter('cps_scheduler_not_allowed', $errors, $entities); return count($errors) == 0; }