$location) { if ($location->op($op)) { $out[$key] = $location; } } } return $out; } /** * Get the location of the given id. */ function backup_migrate_get_location($id) { $locations = backup_migrate_get_locations('all'); return empty($locations[$id]) ? NULL : $locations[$id]; } /** * A base class for creating locations. */ class backup_migrate_location extends backup_migrate_item { var $db_table = "backup_migrate_destinations"; var $type_name = "location"; var $default_values = array('settings' => array()); var $singular = 'location'; var $plural = 'locations'; var $title_plural = 'Locations'; var $title_singular = 'Location'; var $subtype = ""; var $supported_ops = 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('location'); t('locations'); t('Location'); t('Locations'); } function ops() { return $this->supported_ops; } /** * Does this location support the given operation. */ function op($op) { $ops = (array)$this->ops(); return in_array($op, $ops); } /** * Remove the given op from the support list. */ function remove_op($op) { $key = array_search($op, $this->supported_ops); if ($key !== FALSE) { unset($this->supported_ops[$key]); } } function get_name() { return @$this->name; } function set_name($name) { return $this->name = $name; } function set_location($location) { $this->location = $location; } function get_location() { return @$this->location; } function get_display_location() { return $this->get_location(); } function settings($key = NULL) { $out = $this->settings; if ($key) { $out = isset($out[$key]) ? $out[$key] : NULL; } return $out; } /** * Get the type name of this location for display to the user. */ function get_subtype_name() { if ($type = $this->get('subtype')) { $types = $this->location_types(); return isset($types[$type]['type_name']) ? $types[$type]['type_name'] : $type; } } /** * Get the edit form for the item. */ function edit_form() { if (!empty($this->supported_ops)) { $form = parent::edit_form(); $form['subtype'] = array( "#type" => "value", "#default_value" => $this->get('subtype'), ); } else { $types = $this->location_types(); $items = array(); // If no (valid) node type has been provided, display a node type overview. foreach ($types as $key => $type) { if (@$type['can_create']) { $type_url_str = str_replace('_', '-', $key); $out = '
'. l($type['type_name'], BACKUP_MIGRATE_MENU_PATH . "/settings/$this->type_name/add/$type_url_str", array('attributes' => array('title' => t('Add a new @s location.', array('@s' => $type['type_name']))))) .'
'; $out .= '
'. filter_xss_admin($type['description']) .'
'; $items[] = $out; } } if (count($items)) { $output = t('Choose the type of location you would like to create:') .'
'. implode('', $items) .'
'; } else { $output = t('No types available.'); } $form['select_type'] = array( '#type' => 'markup', '#markup' => $output, ); } return $form; } /** * Get the available location types. */ function location_types() { return backup_migrate_get_location_subtypes(); } /** * 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 %name?', array('%name' => $this->get_name())); } /** * 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')), 'subtype_name' => array('title' => t('Type')), 'display_location' => array('title' => t('Location')), ) + $out; return $out; } /** * Get a row of data to be used in a list of items of this type. */ function get_list_row() { $out = parent::get_list_row(); // Supress locations with no actions as there's no value in showing them (and they may confuse new users). if (empty($out['actions'])) { return NULL; } return $out; } /** * Get the action links for a location. */ function get_action_links() { $out = parent::get_action_links(); $item_id = $this->get_id(); // Don't display the download/delete/restore ops if they are not available for this location. if ($this->op('list files') && user_access("access backup files")) { $out = array('list files' => l(t("list files"), BACKUP_MIGRATE_MENU_PATH . "/$this->type_name/list/files/". $item_id)) + $out; } if (!$this->op('configure') || !user_access('administer backup and migrate')) { unset($out['edit']); } return $out; } /** * Determine if we can read the given file. */ function can_read_file($file_id) { return $this->op('restore'); } /** * Get the form for the settings for this location type. */ function settings_default() { return array(); } /** * Get the form for the settings for this location. */ function settings_form($form) { return $form; } /** * Validate the form for the settings for this location. */ function settings_form_validate($form_values) { } /** * Submit the settings form. Any values returned will be saved. */ function settings_form_submit($form_values) { return $form_values; } /** * Get the form for the settings for this filter. */ function backup_settings_default() { return array(); } /** * Get the form for the settings for this filter. */ function backup_settings_form($settings) { return array(); } /** * Get the form for the settings for this filter. */ function backup_settings_form_validate($form, &$form_state) { } /** * Submit the settings form. Any values returned will be saved. */ function backup_settings_form_submit($form, &$form_state) { } /** * Get the form for the settings for this filter. */ function restore_settings_default() { return array(); } /** * Get the form for the settings for this filter. */ function restore_settings_form($settings) { return array(); } /** * Get the form for the settings for this filter. */ function restore_settings_form_validate($form_values) { } /** * Submit the settings form. Any values returned will be saved. */ function restore_settings_form_submit($form_values) { return $form_values; } /** * Create a new location of the correct type. */ function create($params = array()) { $out = NULL; $types = backup_migrate_get_location_subtypes(); // Get the type passed in in the params, or if none, check the url for a valid type name. // This is to allow new location type to be specified in the path. $location_type = !empty($params['subtype']) ? $params['subtype'] : NULL; if ($location_type && ($type = @$types[$location_type])) { // Include the necessary file if specified by the type. if (!empty($type['file'])) { require_once './'. $type['file']; } $out = new $type['class']($params + array('subtype' => $location_type)); } if (empty($out)) { $out = parent::create($params); } return $out; } /** * Get a url from the parts. */ function url($hide_password = TRUE) { return $this->glue_url($this->dest_url, $hide_password); } /** * Glue a URLs component parts back into a URL. */ function glue_url($parts, $hide_password = TRUE) { // Obscure the password if we need to. $parts['pass'] = $hide_password ? "" : $parts['pass']; // Assemble the URL. $out = ""; $out .= $parts['scheme'] .'://'; $out .= $parts['user'] ? urlencode($parts['user']) : ''; $out .= ($parts['user'] && $parts['pass']) ? ":". urlencode($parts['pass']) : ''; $out .= ($parts['user'] || $parts['pass']) ? "@" : ""; $out .= $parts['host']; $out .= !empty($parts['port']) ? ':'. $parts['port'] : ''; $out .= "/". $parts['path']; return $out; } /** * Break a URL into it's component parts. */ function set_url($url) { $parts = (array)parse_url($url); $parts['user'] = urldecode(@$parts['user']); $parts['pass'] = urldecode(@$parts['pass']); $parts['path'] = urldecode(@$parts['path']); $parts['path'] = ltrim(@$parts['path'], "/"); $this->dest_url = $parts; } /** * Retrieve a list of filetypes supported by this source/destination. */ function file_types() { return array(); } } /** * A base class for creating locations. */ class backup_migrate_location_remote extends backup_migrate_location { /** * The location is a URI so parse it and store the parts. */ function get_location() { return $this->url(FALSE); } /** * The location to display is the url without the password. */ function get_display_location() { return $this->url(TRUE); } /** * Return the location with the password. */ function set_location($location) { $this->location = $location; $this->set_url($location); } /** * Get a url from the parts. */ function url($hide_password = TRUE) { return $this->glue_url($this->dest_url, $hide_password); } /** * Glue a URLs component parts back into a URL. */ function glue_url($parts, $hide_password = TRUE) { // Obscure the password if we need to. $parts['pass'] = $hide_password ? "" : $parts['pass']; // Assemble the URL. $out = ""; $out .= $parts['scheme'] .'://'; $out .= $parts['user'] ? urlencode($parts['user']) : ''; $out .= ($parts['user'] && $parts['pass']) ? ":". urlencode($parts['pass']) : ''; $out .= ($parts['user'] || $parts['pass']) ? "@" : ""; $out .= $parts['host']; $out .= !empty($parts['port']) ? ':'. $parts['port'] : ''; $out .= "/". $parts['path']; return $out; } /** * Break a URL into it's component parts. */ function set_url($url) { $parts = (array)parse_url($url); $parts['user'] = urldecode(@$parts['user']); $parts['pass'] = urldecode(@$parts['pass']); $parts['path'] = urldecode(@$parts['path']); $parts['path'] = ltrim(@$parts['path'], "/"); $this->dest_url = $parts; } /** * location configuration callback. */ function edit_form() { $form = parent::edit_form(); $form['scheme'] = array( "#type" => "select", "#title" => t("Scheme"), "#default_value" => @$this->dest_url['scheme'] ? $this->dest_url['scheme'] : 'mysql', "#required" => TRUE, "#options" => array($GLOBALS['db_type'] => $GLOBALS['db_type']), "#weight" => 0, ); $form['host'] = array( "#type" => "textfield", "#title" => t("Host"), "#default_value" => @$this->dest_url['host'] ? $this->dest_url['host'] : 'localhost', "#required" => TRUE, "#weight" => 10, ); $form['path'] = array( "#type" => "textfield", "#title" => t("Path"), "#default_value" => @$this->dest_url['path'], "#required" => TRUE, "#weight" => 20, ); $form['user'] = array( "#type" => "textfield", "#title" => t("Username"), "#default_value" => @$this->dest_url['user'], "#required" => TRUE, "#weight" => 30, ); $form['pass'] = array( "#type" => "password", "#title" => t("Password"), "#default_value" => @$this->dest_url['pass'], '#description' => '', "#weight" => 40, ); if (@$this->dest_url['pass']) { $form['old_password'] = array( "#type" => "value", "#value" => @$this->dest_url['pass'], ); $form['pass']["#description"] .= t(' You do not need to enter a password unless you wish to change the currently saved password.'); } return $form; } /** * Submit the configuration form. Glue the url together and add the old password back if a new one was not specified. */ function edit_form_submit($form, &$form_state) { $form_state['values']['pass'] = $form_state['values']['pass'] ? $form_state['values']['pass'] : $form_state['values']['old_password']; $form_state['values']['location'] = $this->glue_url($form_state['values'], FALSE); parent::edit_form_submit($form, $form_state); } }