<?php
pb_backupbuddy::load_script( 'jquery-ui-datepicker', true ); // WP core script.
pb_backupbuddy::load_script( 'jquery-ui-slider', true ); // WP core script.
pb_backupbuddy::load_script( 'timepicker.js' );
pb_backupbuddy::load_style( 'admin.css', false ); // Plugin-specific file.
pb_backupbuddy::load_style( 'jquery_smoothness.css', false ); // Plugin-specific file.
?>
<script type="text/javascript">
jQuery(document).ready(function(){
// WP 3.2.1 does not like the datepicker and breaks other JS so we omit it if it failed to load properly.
if (jQuery.isFunction(jQuery.fn.datepicker)) {
jQuery( '#pb_backupbuddy_first_run' ).datetimepicker({
ampm: true
});
}
});
</script>
<?php
backupbuddy_core::versions_confirm();
$date_format_example = 'mm/dd/yyyy hh:mm [am/pm]'; // Example date format for displaying to user.
/***** BEGIN SCHEDULE DELETION *****/
if ( pb_backupbuddy::_POST( 'bulk_action' ) == 'delete_schedule' ) {
pb_backupbuddy::verify_nonce( pb_backupbuddy::_POST( '_wpnonce' ) ); // Security check to prevent unauthorized deletions by posting from a remote place.
$deleted_schedules = array();
foreach( pb_backupbuddy::_POST( 'items' ) as $id ) {
$deleted_schedules[] = htmlentities( pb_backupbuddy::$options['schedules'][$id]['title'] );
backupbuddy_api::deleteSchedule( $id, $confirm = true );
} // end foreach.
pb_backupbuddy::alert( __( 'Deleted schedule(s):', 'it-l10n-backupbuddy' ) . ' ' . implode( ', ', $deleted_schedules ) );
}
/***** END SCHEDULE DELETION *****/
/***** BEGIN MANUALLY RUNNING SCHEDULE *****/
if ( pb_backupbuddy::_GET( 'run' ) != '' ) {
pb_backupbuddy::alert( 'Manually running scheduled backup "' . pb_backupbuddy::$options['schedules'][pb_backupbuddy::_GET( 'run' )]['title'] . '" in the background.' . '<br>' .
__( 'Note: If there is no site activity there may be delays between steps in the backup. Access the site or use a 3rd party service, such as a free pinging service, to generate site activity.', 'it-l10n-backupbuddy' ) );
pb_backupbuddy_cron::_run_scheduled_backup( (int)pb_backupbuddy::_GET( 'run' ) );
}
/***** END MANUALLY RUNNING SCHEDULE *****/
function bb_build_remote_destinations( $destinations_list ) {
$remote_destinations = explode( '|', $destinations_list );
$remote_destinations_html = '';
foreach( $remote_destinations as $destination ) {
if ( isset( $destination ) && ( $destination != '' ) ) {
$remote_destinations_html .= '<li id="pb_remotedestination_' . $destination . '">';
if ( ! isset( pb_backupbuddy::$options['remote_destinations'][$destination] ) ) {
$remote_destinations_html .= '{destination no longer exists}';
} else {
$remote_destinations_html .= pb_backupbuddy::$options['remote_destinations'][$destination]['title'];
$remote_destinations_html .= ' (' . backupbuddy_core::pretty_destination_type( pb_backupbuddy::$options['remote_destinations'][$destination]['type'] ) . ') ';
}
$remote_destinations_html .= '<img class="pb_remotedestionation_delete" src="' . pb_backupbuddy::plugin_url() . '/images/redminus.png" style="vertical-align: -3px; cursor: pointer;" title="' . __( 'Remove remote destination from this schedule.', 'it-l10n-backupbuddy' ) . '" />';
$remote_destinations_html .= '</li>';
}
}
$remote_destinations = '<ul id="pb_backupbuddy_remotedestinations_list">' . $remote_destinations_html . '</ul>';
return $remote_destinations;
}
// EDIT existing schedule.
if ( pb_backupbuddy::_GET( 'edit' ) != '' ) {
$mode = 'edit';
$data['mode_title'] = __('Save Schedule', 'it-l10n-backupbuddy' );
$savepoint = 'schedules#' . pb_backupbuddy::_GET( 'edit' );
$next_run = wp_next_scheduled( 'backupbuddy_cron', array( 'run_scheduled_backup', array( (int)pb_backupbuddy::_GET( 'edit' ) ) ) );
if ( ( ! is_numeric( $next_run ) ) || ( 0 == $next_run ) ) { // Unable to determine next runtime so just set to now.
$next_run = time();
}
$first_run_value = date('m/d/Y h:i a', $next_run + ( get_option( 'gmt_offset' ) * 3600 ) ); // pb_backupbuddy::$options['schedules'][pb_backupbuddy::_GET( 'edit' )]['first_run']
if ( '' != pb_backupbuddy::_POST( 'pb_backupbuddy_remote_destinations' ) ) {
$destination_list = pb_backupbuddy::_POST( 'pb_backupbuddy_remote_destinations' );
} else {
$destination_list = pb_backupbuddy::$options['schedules'][pb_backupbuddy::_GET( 'edit' )]['remote_destinations'];
}
$remote_destinations = bb_build_remote_destinations( $destination_list );
} else { // ADD new schedule.
$mode = 'add';
$data['mode_title'] = __('Add New Schedule', 'it-l10n-backupbuddy' );
$savepoint = false;
$first_run_value = date('m/d/Y h:i a', time() + ( ( get_option( 'gmt_offset' ) * 3600 ) + 86400 ) );
$remote_destinations = '<ul id="pb_backupbuddy_remotedestinations_list"></ul>';
}
$schedule_form = new pb_backupbuddy_settings( 'scheduling', $savepoint, 'edit=' . pb_backupbuddy::_GET( 'edit' ), 250 );
$schedule_form->add_setting( array(
'type' => 'text',
'name' => 'title',
'title' => 'Schedule name',
'tip' => __('This is a name for your reference only.', 'it-l10n-backupbuddy' ),
'rules' => 'required',
) );
$profile_list = array();
foreach( pb_backupbuddy::$options['profiles'] as $profile_id => $profile ) {
if ( $profile_id == 0 ) { continue; } // default profile.
if ( $profile['type'] == 'full' ) {
$pretty_type = 'Full';
} elseif ( $profile['type'] == 'db' ) {
$pretty_type = 'Database Only';
} elseif ( $profile['type'] == 'files' ) {
$pretty_type = 'Files Only';
} else {
$pretty_type = 'Unknown';
}
$profile_list[ $profile_id ] = htmlentities( $profile['title'] ) . ' (' . $pretty_type . ')';
}
$schedule_form->add_setting( array(
'type' => 'select',
'name' => 'profile',
'title' => 'Backup profile',
'options' => $profile_list,
'tip' => __( 'Full backups contain all files (except exclusions) and your database. Database only backups consist of an export of your mysql database; no WordPress files or media. Database backups are typically much smaller and faster to perform and are typically the most quickly changing part of a site.', 'it-l10n-backupbuddy' ),
'rules' => 'required',
) );
if ( pb_backupbuddy::_GET( 'edit' ) != '' ) {
$defaultInterval = null;
} else {
$defaultInterval = 'daily';
}
$intervalArray = array();
$schedule_intervals = wp_get_schedules();
foreach( $schedule_intervals as $interval_tag => $schedule_interval ) {
$intervalArray[ $schedule_interval['interval'] ] = array( $interval_tag, $schedule_interval['display'] );
}
ksort( $intervalArray );
$intervalArray = array_reverse( $intervalArray );
$intervals = array();
foreach( $intervalArray as $interval ) {
$intervals[ $interval[0] ] = $interval[1];
}
unset( $intervalArray );
$schedule_form->add_setting( array(
'type' => 'select',
'name' => 'interval',
'title' => 'Backup interval',
'options' => $intervals,
'default' => $defaultInterval,
'tip' => __( 'Time period between backups.', 'it-l10n-backupbuddy' ),
'rules' => 'required',
'after' => ' <span class="pb_label">Tip</span> Unsure how often to schedule? Try starting with daily database-only and weekly full backups.',
) );
$schedule_form->add_setting( array(
'type' => 'text',
'name' => 'first_run',
'title' => 'Date/time of next run',
'tip' => __( 'IMPORTANT: For scheduled events to occur someone (or you) must visit this site on or after the scheduled time. If no one visits your site for a long period of time some backup events may not be triggered.', 'it-l10n-backupbuddy' ),
'rules' => 'required',
'default' => $first_run_value,
'after' => ' ' . __('Currently', 'it-l10n-backupbuddy' ) . ' <code>' . date( 'm/d/Y h:i a ' . get_option( 'gmt_offset' ), time() + ( get_option( 'gmt_offset' ) * 3600 ) ) . ' UTC</code> ' . __('based on', 'it-l10n-backupbuddy' ) . ' <a href="' . admin_url( 'options-general.php' ) . '">' . __( 'WordPress settings', 'it-l10n-backupbuddy' ) . '</a>.',
) );
$schedule_form->add_setting( array(
'type' => 'text',
'name' => 'remote_destinations',
'title' => 'Remote backup destination(s)',
'rules' => '',
'css' => 'display: none;',
'after' => $remote_destinations . '<a href="' . pb_backupbuddy::ajax_url( 'destination_picker' ) . '&selecting=1&TB_iframe=1&width=640&height=600" class="thickbox button secondary-button" style="margin-top: 3px;" title="' . __( 'Select a Destination', 'it-l10n-backupbuddy' ) . '">' . __('+ Add Remote Destination', 'it-l10n-backupbuddy' ) . '</a>',
) );
$schedule_form->add_setting( array(
'type' => 'checkbox',
'name' => 'delete_after',
'title' => ' ',
'after' => ' '. __( 'Delete local backup file after remote send success', 'it-l10n-backupbuddy' ),
'options' => array( 'checked' => '1', 'unchecked' => '0' ),
'rules' => '',
) );
if ( pb_backupbuddy::_GET( 'edit' ) != '' ) {
$defaultOnOff = null;
} else {
$defaultOnOff = '1';
}
$schedule_form->add_setting( array(
'type' => 'checkbox',
'name' => 'on_off',
'title' => 'Schedule enabled?',
'options' => array( 'checked' => '1', 'unchecked' => '0' ),
'default' => $defaultOnOff,
'tip' => __( '[Default: enabled] When disabled this schedule will be effectively turned off. This scheduled backup will not occur when disabled / off. You can re-enable schedules by editing them.', 'it-l10n-backupbuddy' ),
'after' => ' ' . __( 'Enable schedule to run', 'it-l10n-backupbuddy' ),
) );
/***** BEGIN ADDING (or editing) SCHEDULE AND PROCESSING FORM *****/
$submitted_schedule = $schedule_form->process(); // Handles processing the submitted form (if applicable).
if ( ( $submitted_schedule != '' ) && ( count ( $submitted_schedule['errors'] ) == 0 ) ) {
// ADD SCHEDULE.
if ( pb_backupbuddy::_GET( 'edit' ) == '' ) { // ADD SCHEDULE.
$error = false;
// Don't allow 'delete file after send to destination' if no destination picked.
if ( ( $submitted_schedule['data']['delete_after'] == '1' ) && ( '' == trim( $submitted_schedule['data']['remote_destinations'] ) ) ) {
pb_backupbuddy::alert( 'Error: You have selected to delete backups after sending but did not specify any remote destinations. Click "Add Remote Destination" to select a destination.', true );
$error = true;
}
if ( ( $submitted_schedule['data']['first_run'] == 0 ) || ( $submitted_schedule['data']['first_run'] == 18000 ) ) {
pb_backupbuddy::alert( sprintf(__('Invalid time format. Please use the specified format / example %s', 'it-l10n-backupbuddy' ) , $date_format_example) );
$error = true;
}
$remote_destinations = trim( $submitted_schedule['data']['remote_destinations'], '|' );
$remote_destinations = explode( '|', $remote_destinations );
if ( '1' == $submitted_schedule['data']['delete_after'] ) {
$delete_after = true;
} else {
$delete_after = false;
}
if ( ! isset( $submitted_schedule['data']['on_off'] ) || ( '1' == $submitted_schedule['data']['on_off'] ) ) {
$enabled = true;
} else {
$enabled = false;
}
if ( $error === false ) {
$add_response = backupbuddy_api::addSchedule(
$title = $submitted_schedule['data']['title'],
$profile = $submitted_schedule['data']['profile'],
$interval = $submitted_schedule['data']['interval'],
$first_run = pb_backupbuddy::$format->unlocalize_time( strtotime( $submitted_schedule['data']['first_run'] ) ),
$remote_destinations,
$delete_after,
$enabled
);
if ( true !== $add_response ) {
pb_backupbuddy::alert( 'Error scheduling: ' . $add_response );
} else { // Success
pb_backupbuddy::save();
$schedule_form->clear_values();
$schedule_form->set_value( 'on_off', 1 );
pb_backupbuddy::alert( 'Added new schedule `' . htmlentities( $submitted_schedule['data']['title'] ) . '`.' );
}
}
} else { // EDIT SCHEDULE. Form handles saving; just need to update timestamp.
$first_run = pb_backupbuddy::$format->unlocalize_time( strtotime( $submitted_schedule['data']['first_run'] ) );
if ( ( $first_run == 0 ) || ( $first_run == 18000 ) ) {
pb_backupbuddy::alert( sprintf(__('Invalid time format. Please use the specified format / example %s', 'it-l10n-backupbuddy' ) , $date_format_example) );
$error = true;
}
pb_backupbuddy::$options['schedules'][pb_backupbuddy::_GET( 'edit' )]['first_run'] = $first_run;
//echo 'first: ' . $first_run;
$next_scheduled_time = wp_next_scheduled( 'backupbuddy_cron', array( 'run_scheduled_backup', array( (int)$_GET['edit'] ) ) );
$result = backupbuddy_core::unschedule_event( $next_scheduled_time, 'backupbuddy_cron', array( 'run_scheduled_backup', array( (int)$_GET['edit'] ) ) ); // Remove old schedule. pb_backupbuddy::$options['schedules'][$_GET['edit']]['first_run']
if ( $result === FALSE ) {
pb_backupbuddy::alert( 'Error #589689. Unable to unschedule scheduled cron job with WordPress. Please see your BackupBuddy error log for details.' );
}
$result = backupbuddy_core::schedule_event( $first_run, $submitted_schedule['data']['interval'], 'run_scheduled_backup', array( (int)$_GET['edit'] ) ); // Add new schedule.
if ( $result === FALSE ) {
pb_backupbuddy::alert( 'Error scheduling event with WordPress. Your schedule may not work properly. Please try again. Error #3488439. Check your BackupBuddy error log for details.', true );
}
pb_backupbuddy::save();
//pb_backupbuddy::alert( 'Edited schedule `' . htmlentities( $submitted_schedule['data']['title'] ) . '`.' );
$editedSchedule = $submitted_schedule['data'];
backupbuddy_core::addNotification( 'schedule_updated', 'Backup schedule updated', 'An existing schedule "' . $editedSchedule['title'] . '" has been updated.', $editedSchedule );
}
} elseif ( count ( $submitted_schedule['errors'] ) > 0 ) {
foreach( $submitted_schedule['errors'] as $error ) {
pb_backupbuddy::alert( $error );
}
}
$data['schedule_form'] = $schedule_form;
/***** END ADDING (or editing) SCHEDULE AND PROCESSING FORM *****/
// Validate that all internal schedules are properly registered in the WordPress cron.
require_once( pb_backupbuddy::plugin_path() . '/classes/housekeeping.php' );
backupbuddy_housekeeping::validate_bb_schedules_in_wp();
$schedules = array();
foreach ( pb_backupbuddy::$options['schedules'] as $schedule_id => $schedule ) {
$profile = pb_backupbuddy::$options['profiles'][ (int)$schedule['profile'] ];
$title = esc_html( $schedule['title'] );
if ( $profile['type'] == 'full' ) {
$type = 'Full';
} elseif ( $profile['type'] == 'files' ) {
$type = 'Files only';
} elseif ( $profile['type'] == 'db' ) {
$type = 'Database only';
} else {
$type = 'Unknown (' . $schedule['type'] . ')';
}
$type = $profile['title'] . ' (' . $type . ')';
$interval = $schedule['interval'];
if ( isset( $schedule['on_off'] ) && ( $schedule['on_off'] == '0' ) ) {
$on_off = '<font color=red>Disabled</font>';
} else {
$on_off = 'Enabled';
}
$destinations = explode( '|', $schedule['remote_destinations'] );
$destination_array = array();
foreach( $destinations as &$destination ) {
if ( isset( $destination ) && ( $destination != '' ) ) {
if ( ! isset( pb_backupbuddy::$options['remote_destinations'][$destination] ) ) {
pb_backupbuddy::alert( 'The schedule `' . $title . '` is set to send to a remote destination which no longer exists. Please edit it and remove the invalid destination.' );
$destination_array[] = '{destination no longer exists}';
} else {
$destination_array[] = pb_backupbuddy::$options['remote_destinations'][$destination]['title'] . ' [' . backupbuddy_core::pretty_destination_type( pb_backupbuddy::$options['remote_destinations'][$destination]['type'] ) . ']';
}
}
}
$destinations = implode( ', ', $destination_array );
if ( count( $destination_array ) > 0 ) {
if ( $schedule['delete_after'] == '1' ) {
$destinations .= '<br>' . '<span class="description">Delete local backup file after send</span>';
} else {
$destinations .= '<br>' . '<span class="description">Do not delete local backup file after send</span>';
}
} else {
$destinations = '<span class="description">None</span>';
}
// Determine first run.
$first_run = pb_backupbuddy::$format->date( pb_backupbuddy::$format->localize_time( $schedule['first_run'] ) );
// Determine last run.
if ( isset( $schedule['last_run'] ) ) { // backward compatibility before last run tracking added. Pre v2.2.11. Eventually remove this.
if ( $schedule['last_run'] == 0 ) {
$last_run = '<i>' . __( 'Never', 'it-l10n-backupbuddy' ) . '</i>';
} else {
$last_run = pb_backupbuddy::$format->date( pb_backupbuddy::$format->localize_time( $schedule['last_run'] ) );
}
} else { // backward compatibility for before last run tracking was added.
$last_run = '<i> ' . __( 'Unknown', 'it-l10n-backupbuddy' ) . '</i>';
}
// Determine next run.
$next_run = wp_next_scheduled( 'backupbuddy_cron', array( 'run_scheduled_backup', array( (int)$schedule_id ) ) );
if ( false === $next_run ) {
$next_run = '<font color=red>Error: Cron event not found</font>';
pb_backupbuddy::alert( 'Error #874784. WordPress scheduled cron event not found. See "Next Run" time in the schedules list below for problem schedule. This may be caused by a conflicting plugin deleting the schedule or manual deletion. Try editing or deleting and re-creating the schedule.', true );
} else {
$next_run = pb_backupbuddy::$format->date( pb_backupbuddy::$format->localize_time( $next_run ) );
}
$run_time = 'First run: ' . $first_run . '<br>' .
'Last run: ' . $last_run . '<br>' .
'Next run: ' . $next_run;
$schedules[$schedule_id] = array(
$title,
$type,
$interval,
$destinations,
$run_time,
$on_off,
);
} // End foreach.
$data['schedules'] = $schedules;
// Load view.
pb_backupbuddy::load_view( 'scheduling', $data );