class backup_migrate_schedule

  1. nittany7 modules/contrib/backup_migrate/includes/schedules.inc backup_migrate_schedule
  2. mooc7 modules/contrib/backup_migrate/includes/schedules.inc backup_migrate_schedule

A schedule class for crud operations.

Hierarchy

Expanded class hierarchy of backup_migrate_schedule

Members

Contains filters are case sensitive
Namesort descending Modifiers Type Description
backup_migrate_item::all_items function Get all of the given items.
backup_migrate_item::create function Create a new items with the given input. Doesn't load the parameters, but could use them to determine what type to create.
backup_migrate_item::decode_db_row function Decode a loaded db row (unserialize necessary fields).
backup_migrate_item::delete function Delete the item from the database.
backup_migrate_item::export function Return as an exported array of values.
backup_migrate_item::from_array function Load an existing item from an array.
backup_migrate_item::generate_id function Return a random (very very likely unique) string id for a new item.
backup_migrate_item::get function Get the member with the given key.
backup_migrate_item::get_actions function Get the rendered action links for a destination.
backup_migrate_item::get_action_links function Get the action links for a destination.
backup_migrate_item::get_id function Get the primary id for this item (if any is set).
backup_migrate_item::get_list function Get a table of all items of this type.
backup_migrate_item::get_list_header function Get header for a lost of this type.
backup_migrate_item::get_menu_items function Get the menu items for manipulating this type.
backup_migrate_item::get_name function Get the name of the item.
backup_migrate_item::get_primary_key function Get the primary key field title from the schema.
backup_migrate_item::get_schema function Get the schema for the item type.
backup_migrate_item::get_serialized_fields function Return the fields which must be serialized before saving to the db.
backup_migrate_item::item function A particular item.
backup_migrate_item::load_row function Load an existing item from an database (serialized) array.
backup_migrate_item::save function Save the item to the database.
backup_migrate_item::set_id function Set the primary id for this item (if any is set).
backup_migrate_item::to_array function Return as an array of values.
backup_migrate_item::__construct function Constructor, set the basic info pulled from the db or generated programatically.
backup_migrate_schedule::cron function Perform the cron action. Run the backup if enough time has elapsed.
backup_migrate_schedule::delete_confirm_message function Get the message to send to the user when confirming the deletion of the item. Overrides backup_migrate_item::delete_confirm_message
backup_migrate_schedule::edit_form function Get the edit form. Overrides backup_migrate_item::edit_form
backup_migrate_schedule::edit_form_submit function Submit the edit form. Overrides backup_migrate_item::edit_form_submit
backup_migrate_schedule::edit_form_validate function Submit the edit form. Overrides backup_migrate_item::edit_form_validate
backup_migrate_schedule::frequency_periods function Get a list of available backup periods. Only returns time periods which have a (reasonably) consistent number of seconds (ie: no months).
backup_migrate_schedule::get_default_values function Get the default values for this item. Overrides backup_migrate_item::get_default_values
backup_migrate_schedule::get_destination function Get the destination object of the schedule.
backup_migrate_schedule::get_destination_name function Get the name of the destination.
backup_migrate_schedule::get_enabled_description function Format the enabled status in human-readable form.
backup_migrate_schedule::get_exclude_tables_count function Get the number of excluded tables.
backup_migrate_schedule::get_frequency_description function Format a frequency in human-readable form.
backup_migrate_schedule::get_frequency_period function Get the period of the frequency (ie: seconds, minutes etc.)
backup_migrate_schedule::get_keep_description function Format the number to keep in human-readable form.
backup_migrate_schedule::get_last_run function Set the last run time of a schedule to the given timestamp, or now if none specified.
backup_migrate_schedule::get_last_run_description function Format the enabled status in human-readable form.
backup_migrate_schedule::get_list_column_info function Get the columns needed to list the type. Overrides backup_migrate_item::get_list_column_info
backup_migrate_schedule::get_list_row function Get a row of data to be used in a list of items of this type. Overrides backup_migrate_item::get_list_row
backup_migrate_schedule::get_nodata_tables_count function Get the number of excluded tables.
backup_migrate_schedule::get_profile function Get the destination of the schedule.
backup_migrate_schedule::get_profile_name function Get the name of the source.
backup_migrate_schedule::is_enabled function Is the schedule enabled and valid.
backup_migrate_schedule::remove_expired_backups function Remove older backups keeping only the number specified by the aministrator.
backup_migrate_schedule::strings function This function is not supposed to be called. It is just here to help the po extractor out. Overrides backup_migrate_item::strings
backup_migrate_schedule::update_last_run function Set the last run time of a schedule to the given timestamp, or now if none specified.

File

modules/contrib/backup_migrate/includes/schedules.inc, line 44
All of the schedule handling code needed for Backup and Migrate.

View source
class backup_migrate_schedule extends backup_migrate_item {
  var $db_table = "backup_migrate_schedules";
  var $type_name = 'schedule';
  var $singular = 'schedule';
  var $plural = 'schedules';
  var $default_values = array();

  /**
   * This function is not supposed to be called. It is just here to help the po extractor out.
   */
  function strings() {
    // Help the pot extractor find these strings.
    t('Schedule');
    t('Schedules');
    t('schedule');
    t('schedules');
  }

  /**
   * Get the default values for this item.
   */
  function get_default_values() {
    return array(
      'name' => t("Untitled Schedule"),
      'source_id' => 'db',
      'enabled' => 1,
      'keep' => 0,
      'period' => 60 * 60 * 24,
      'storage' => BACKUP_MIGRATE_STORAGE_NONE,
    );
  }

  /**
   * Get the columns needed to list the type.
   */
  function get_list_column_info() {
    $out = parent::get_list_column_info();
    $out = array(
      'name' => array('title' => t('Name')),
      'destination_name' => array(
        'title' => t('Destination'),
        'html' => TRUE,
      ),
      'profile_name' => array(
        'title' => t('Profile'),
        'html' => TRUE,
      ),
      'frequency_description' => array('title' => t('Frequency')),
      'keep_description' => array('title' => t('Keep')),
      'enabled_description' => array('title' => t('Enabled')),
      'last_run_description' => array('title' => t('Last run')),
    ) + $out;
    return $out;
  }

  /**
   * Get a row of data to be used in a list of items of this type.
   */
  function get_list_row() {
    drupal_add_css(drupal_get_path('module', 'backup_migrate') . '/backup_migrate.css');
    $row = parent::get_list_row();
    if (!$this->is_enabled()) {
      foreach ($row as $key => $field) {
        $row[$key] = array(
          'data' => $field,
          'class' => 'schedule-list-disabled',
        );
      }
    }
    return $row;
  }

  /**
   * Is the schedule enabled and valid.
   */
  function is_enabled() {
    $destination = $this->get_destination();
    $profile = $this->get_profile();
    return (!empty($this->enabled) && !empty($destination) && !empty($profile));
  }

  /**
   * Get the destination object of the schedule.
   */
  function get_destination() {
    backup_migrate_include('destinations');
    return backup_migrate_get_destination($this->get('destination_id'));
  }

  /**
   * Get the name of the destination.
   */
  function get_destination_name() {
    if ($destination = $this->get_destination()) {
      return check_plain($destination->get_name());
    }
    return '<div class="row-error">' . t("Missing") . '</div>';
  }

  /**
   * Get the destination of the schedule.
   */
  function get_profile() {
    backup_migrate_include('profiles');
    return backup_migrate_get_profile($this->get('profile_id'));
  }

  /**
   * Get the name of the source.
   */
  function get_profile_name() {
    if ($profile = $this->get_profile()) {
      return check_plain($profile->get_name());
    }
    return '<div class="row-error">' . t("Missing") . '</div>';
  }

  /**
   * Format a frequency in human-readable form.
   */
  function get_frequency_description() {
    $period = $this->get_frequency_period();
    $out = format_plural(($this->period / $period['seconds']), $period['singular'], $period['plural']);
    return $out;
  }

  /**
   * Format the number to keep in human-readable form.
   */
  function get_keep_description() {
    return !empty($this->keep) ? $this->keep : t('All');
  }

  /**
   * Format the enabled status in human-readable form.
   */
  function get_enabled_description() {
    return !empty($this->enabled) ? t('Enabled') : t('Disabled');
  }

  /**
   * Format the enabled status in human-readable form.
   */
  function get_last_run_description() {
    $last_run = $this->get('last_run');
    return !empty($last_run) ? format_date($last_run, 'small') : t('Never');
  }

  /**
   * Get the number of excluded tables.
   */
  function get_exclude_tables_count() {
    return count($this->exclude_tables) ? count($this->exclude_tables) : t("No tables excluded");
  }

  /**
   * Get the number of excluded tables.
   */
  function get_nodata_tables_count() {
    return count($this->nodata_tables) ? count($this->nodata_tables) : t("No data omitted");
  }

  /**
   * Get the edit form.
   */
  function edit_form() {
    $form = parent::edit_form();
    backup_migrate_include('destinations', 'profiles');

    $form['enabled'] = array(
      "#type" => "checkbox",
      "#title" => t("Enabled"),
      "#default_value" => $this->get('enabled'),
    );
    $form['name'] = array(
      "#type" => "textfield",
      "#title" => t("Schedule Name"),
      "#default_value" => $this->get('name'),
    );

    $form += _backup_migrate_get_source_form($this->get('source_id'));

    $form['profile_id'] = array(
      "#type" => "select",
      "#title" => t("Settings Profile"),
      "#options" => _backup_migrate_get_profile_form_item_options(),
      "#default_value" => $this->get('profile_id'),
    );
    $form['profile_id']['#description'] = ' ' . l(t("Create new profile"), BACKUP_MIGRATE_MENU_PATH . "/profile/add");
    if (!$form['profile_id']['#options']) {
      $form['profile_id']['#options'] = array('0' => t('-- None Available --'));
    }

    $period_options = array();
    foreach ($this->frequency_periods() as $type => $period) {
      $period_options[$type] = $period['title'];
    }
    $default_period = $this->get_frequency_period();
    $default_period_num = $this->get('period') / $default_period['seconds'];

    $form['period'] = array(
      "#type" => "item",
      "#title" => t("Backup every"),
      "#prefix" => '<div class="container-inline">',
      "#suffix" => '</div>',
      "#tree" => TRUE,
    );
    $form['period']['number'] = array(
      "#type" => "textfield",
      "#size" => 6,
      "#default_value" => $default_period_num,
    );
    $form['period']['type'] = array(
      "#type" => "select",
      "#options" => $period_options,
      "#default_value" => $default_period['type'],
    );

    $form['keep'] = array(
      "#type" => "textfield",
      "#size" => 6,
      "#title" => t("Number of Backup files to keep"),
      "#description" => t("The number of backup files to keep before deleting old ones. Use 0 to never delete backups. <strong>Other files in the destination directory will get deleted if you specify a limit.</strong>"),
      "#default_value" => $this->get('keep'),
    );
    $destination_options = _backup_migrate_get_destination_form_item_options('scheduled backup');
    $form['destination_id'] = array(
      "#type" => "select",
      "#title" => t("Destination"),
      "#description" => t("Choose where the backup file will be saved. Backup files contain sensitive data, so be careful where you save them."),
      "#options" => $destination_options,
      "#default_value" => $this->get('destination_id'),
    );
    $form['destination_id']['#description'] .= ' ' . l(t("Create new destination"), BACKUP_MIGRATE_MENU_PATH . "/destination/add");

    return $form;
  }

  /**
   * Submit the edit form.
   */
  function edit_form_validate($form, &$form_state) {
    if (!is_numeric($form_state['values']['period']['number']) || $form_state['values']['period']['number'] <= 0) {
      form_set_error('period][number', t('Backup period must be a number greater than 0.'));
    }
    if (!is_numeric($form_state['values']['keep']) || $form_state['values']['keep'] < 0) {
      form_set_error('keep', t('Number to keep must be an integer greater than or equal to 0.'));
    }
    parent::edit_form_validate($form, $form_state);
  }

  /**
   * Submit the edit form.
   */
  function edit_form_submit($form, &$form_state) {
    $periods = $this->frequency_periods();
    $period = $periods[$form_state['values']['period']['type']];
    $form_state['values']['period'] = $form_state['values']['period']['number'] * $period['seconds'];
    parent::edit_form_submit($form, $form_state);
  }

  /**
   * Get the period of the frequency (ie: seconds, minutes etc.)
   */
  function get_frequency_period() {
    foreach (array_reverse($this->frequency_periods()) as $period) {
      if ($period['seconds'] && ($this->period % $period['seconds']) === 0) {
        return $period;
      }
    }
  }

  /**
   * Get a list of available backup periods. Only returns time periods which have a
   *  (reasonably) consistent number of seconds (ie: no months).
   */
  function frequency_periods() {
    return array(
      'seconds' => array(
        'type' => 'seconds',
        'seconds' => 1,
        'title' => t('Seconds'),
        'singular' => t('Once a second'),
        'plural' => t('Every @count seconds'),
      ),
      'minutes' => array(
        'type' => 'minutes',
        'seconds' => 60,
        'title' => t('Minutes'),
        'singular' => t('Once a minute'),
        'plural' => t('Every @count minutes'),
      ),
      'hours' => array(
        'type' => 'hours',
        'seconds' => 3600,
        'title' => t('Hours'),
        'singular' => t('Once an hour'),
        'plural' => t('Every @count hours'),
      ),
      'days' => array(
        'type' => 'days',
        'seconds' => 86400,
        'title' => t('Days'),
        'singular' => t('Once a day'),
        'plural' => t('Every @count days'),
      ),
      'weeks' => array(
        'type' => 'weeks',
        'seconds' => 604800,
        'title' => t('Weeks'),
        'singular' => t('Once a week'),
        'plural' => t('Every @count weeks'),
      ),
    );
  }

  /**
   * Get the message to send to the user when confirming the deletion of the item.
   */
  function delete_confirm_message() {
    return t('Are you sure you want to delete the profile %name? Any schedules using this profile will be disabled.', array('%name' => $this->get('name')));
  }

  /**
   * Perform the cron action. Run the backup if enough time has elapsed.
   */
  function cron() {
    $now = time();

    // Add a small negative buffer (1% of the entire period) to the time to account for slight difference in cron run length.
    $wait_time = $this->period - ($this->period * variable_get('backup_migrate_schedule_buffer', 0.01));

    if ($this->is_enabled() && ($now - $this->get('last_run')) >= $wait_time) {
      if ($settings = $this->get_profile()) {
        $settings->destination_id = $this->destination_id;
        $settings->source_id = $this->source_id;
        $this->update_last_run($now);
        backup_migrate_perform_backup($settings);
        $this->remove_expired_backups();
      }
      else {
        backup_migrate_backup_fail("Schedule '%schedule' could not be run because requires a profile which is missing.", array('%schedule' => $schedule->get_name()), $settings);
      }
    }
  }

  /**
   * Set the last run time of a schedule to the given timestamp, or now if none specified.
   */
  function update_last_run($timestamp = NULL) {
    if ($timestamp === NULL) {
      $timestamp = time();
    }
    variable_set('backup_migrate_schedule_last_run_' . $this->get('id'), $timestamp);
  }

  /**
   * Set the last run time of a schedule to the given timestamp, or now if none specified.
   */
  function get_last_run($timestamp = NULL) {
    return variable_get('backup_migrate_schedule_last_run_' . $this->get('id'), 0);
  }


  /**
   * Remove older backups keeping only the number specified by the aministrator.
   */
  function remove_expired_backups() {
    backup_migrate_include('destinations');

    $num_to_keep = $this->keep;
    // If num to keep is not 0 (0 is infinity).
    if ($num_to_keep && ($destination = $this->get_destination())) {
      $i = 0;
      if ($destination->op('delete') && $destination_files = $destination->list_files()) {
        // Sort the files by modified time.
        foreach ($destination_files as $file) {
          if ($file->is_recognized_type() && $destination->can_delete_file($file->file_id())) {
            $files[str_pad($file->info('filetime'), 10, "0", STR_PAD_LEFT) . "-" . $i++] = $file;
          }
        }

        // If we are beyond our limit, remove as many as we need.
        $num_files = count($files);

        if ($num_files > $num_to_keep) {
          $num_to_delete = $num_files - $num_to_keep;
          // Sort by date.
          ksort($files);
          // Delete from the start of the list (earliest).
          for ($i = 0; $i < $num_to_delete; $i++) {
            $file = array_shift($files);
            $destination->delete_file($file->file_id());
          }
        }
      }
    }
  }
}