Hello. I had the followin menu item:
$items['admin/repository/back'] = array(
'title' => 'Backup DataBase',
'access arguments' => array('data'),
'page callback' => 'test',
'page arguments' => array(3),
'type' => MENU_LOCAL_TASK,
'weight' => 3,
);
Now i installed a module (backup and migrate).
I want to know if it is possible to call up that module inside my menu.
something like the callback, but instead of calling the test funcion would call the module backup_and migrate....
I tried something like:
$items['admin/repository/back'] = array(
'title' => 'Backup DataBase',
'access arguments' => array('data'),
'page callback' => 'drupal/admin/content/backup_migrate',
'page arguments' => array(3),
'type' => MENU_LOCAL_TASK,
'weight' => 3,
);
drupal/admin/content/backup_migrate
Comments
The functionality of the
The functionality of the module is already available at admin/content/backup_migrate
yes... i know... but i want,
yes... i know... but i want, if possible, that when i click in item... that it call (goes) there...
that is my doubt, how to do it? if possible, off course.
You have a two options: 1)
You have a two options:
1) You could set your own function and redirect to the page already supplied by the backup and migrate module
2) You can set the page callback to be the function that is called in /admin/content/backup_migrate. So, look in the module and find the menu item for admin/content/backup_migrate and use the page callback parameter you find there.
Cheers,
Chris
Build a Module.com - The definitive video guide to Drupal development
I've recorded over 500 focused Drupal video tutorials at Build a Module.com.
i have no ideia how?
Hey... chrisshattuck.... could you give me a hand on this for your 1s ideia?
i had no ideia how to do it, just as for the second one...on this, i got a blank screen.
function repository_menu(){
module_load_include("module"," backup_migrate.module");
/**
*Main Menu
*/
$items['admin/repository'] = array(
'title' => 'Algorithm Repository',
'access arguments' => array('data'),
'page callback' => 'repository_overview',
'type' => MENU_NORMAL_ITEM,
);
//submenus
//submenu 3
$items['admin/repository/back'] = array(
'title' => 'Backup DataBase',
'access arguments' => array('data'),
'page callback' => 'backup_migrate_backup',
'page arguments' => array(3),
'type' => MENU_LOCAL_TASK,
'weight' => 3,
);
on submenu3, pagecallback i tried to call the menu function, trying to call up the backupmodule (http://drupal.org/project/backup_migrate)
Here's how it would look in
Here's how it would look in your hook_menu:
<?php$items['admin/repository/back'] = array(
'title' => 'Backup DataBase',
'access arguments' => array('data'),
'page callback' => 'mymodule_function_callback',
'page arguments' => array(3),
'type' => MENU_LOCAL_TASK,
'weight' => 3,
);
?>
And then you would define the callback function for the page to redirect to the existing page:
<?phpfunction mymodule_function_callback() {
drupal_goto('admin/content/backup_migrate');
}
?>
Hope that helps!
?>
I've recorded over 500 focused Drupal video tutorials at Build a Module.com.
help on this? 1st point... how to?
Hey... chrisshattuck.... could you give me a hand on this for your 1s ideia?
i had no ideia how to do it, just as for the second one...on this, i got a blank screen.
function repository_menu(){
module_load_include("module"," backup_migrate.module");
/**
*Main Menu
*/
$items['admin/repository'] = array(
'title' => 'Algorithm Repository',
'access arguments' => array('data'),
'page callback' => 'repository_overview',
'type' => MENU_NORMAL_ITEM,
);
//submenus
//submenu 3
$items['admin/repository/back'] = array(
'title' => 'Backup DataBase',
'access arguments' => array('data'),
'page callback' => 'backup_migrate_backup',
'page arguments' => array(3),
'type' => MENU_LOCAL_TASK,
'weight' => 3,
);function repository_menu(){
module_load_include("module"," backup_migrate.module");
/**
*Main Menu
*/
$items['admin/repository'] = array(
'title' => 'Algorithm Repository',
'access arguments' => array('data'),
'page callback' => 'repository_overview',
'type' => MENU_NORMAL_ITEM,
);
//submenus
//submenu 3
$items['admin/repository/back'] = array(
'title' => 'Backup DataBase',
'access arguments' => array('data'),
'page callback' => 'backup_migrate_backup',
'page arguments' => array(3),
'type' => MENU_LOCAL_TASK,
'weight' => 3,
);
The backup module is kind strange... i can't figure out how to call it inside my own module :S
any help?
backup module
<?php
// $Id: backup_migrate.module,v 1.3.2.17 2009/01/18 02:53:16 ronan Exp $
/**
* @file
* Create (manually or scheduled) and restore backups of your Drupal MySQL
* database with an option to exclude table data (f.e. cache_*)
*/
/**
* Implementation of hook_menu().
*/
function backup_migrate_menu() {
$items = array();
$items['admin/content/backup_migrate'] = array(
'title' => t('Backup and Migrate'),
'description' => t('Backup/restore your database or migrate data to or from another Drupal site.'),
'page callback' => 'drupal_get_form',
'page arguments' => array('backup_migrate_backup'),
'access arguments' => array('perform backup'),
'type' => MENU_NORMAL_ITEM,
);
//----came from here
$items['admin/content/backup_migrate/export'] = array(
'title' => t('Backup/Export DB'),
'description' => t('Backup the database.'),
'weight' => 0,
'type' => MENU_DEFAULT_LOCAL_TASK,
);
//--------------------
$items['admin/content/backup_migrate/restore'] = array(
'title' => t('Restore/Import DB'),
'description' => t('Restore the database from a previous backup'),
'page callback' => 'drupal_get_form',
'page arguments' => array('backup_migrate_restore'),
'access arguments' => array('restore from backup'),
'weight' => 1,
'type' => MENU_LOCAL_TASK,
);
$items['admin/content/backup_migrate/files'] = array(
'title' => t('Saved Backups'),
'description' => t('View existing backup files'),
'page callback' => '_backup_migrate_list_files',
'access arguments' => array('access backup files'),
'weight' => 2,
'type' => MENU_LOCAL_TASK,
);
$items['admin/content/backup_migrate/files/manual'] = array(
'title' => t('Manual Backups'),
'page callback' => '_backup_migrate_list_files',
'page arguments' => array('manual'),
'access arguments' => array('access backup files'),
'weight' => 1,
'type' => MENU_DEFAULT_LOCAL_TASK,
);
$items['admin/content/backup_migrate/files/scheduled'] = array(
'title' => t('Scheduled Backups'),
'page callback' => '_backup_migrate_list_files',
'page arguments' => array('scheduled'),
'access arguments' => array('access backup files'),
'weight' => 2,
'type' => MENU_LOCAL_TASK,
);
$items['admin/content/backup_migrate/schedule'] = array(
'title' => t('Backup Schedule'),
'description' => t('View existing backup files'),
'page callback' => 'drupal_get_form',
'page arguments' => array('backup_migrate_schedule'),
'access arguments' => array('access backup files'),
'weight' => 3,
'type' => MENU_LOCAL_TASK,
);
$items['admin/content/backup_migrate/restorefile'] = array(
'title' => t('restore from backup'),
'description' => t('Restore database from a backup file on the server'),
'page callback' => '_backup_migrate_restore_from_server',
'access arguments' => array('restore from backup'),
'type' => MENU_CALLBACK,
);
$items['admin/content/backup_migrate/delete'] = array(
'title' => t('Delete File'),
'description' => t('Delete a backup file'),
'page callback' => '_backup_migrate_delete',
'access arguments' => array('delete backup files'),
'type' => MENU_CALLBACK,
);
return $items;
}
/**
* Implementation of hook_cron(),
*
* Takes care of scheduled backups.
*/
function backup_migrate_cron() {
if ($backup_schedule_period = variable_get("backup_migrate_schedule_backup_period", 0)) {
$last_backup = variable_get("backup_migrate_schedule_last_backup", 0);
$now = time();
if ($last_backup < ($now - ($backup_schedule_period * 60 * 60))) {
// time to run the backup
_backup_migrate_dump_tables(
variable_get("backup_migrate_file_name", _backup_migrate_default_file_name()),
variable_get("backup_migrate_exclude_tables", _backup_migrate_default_exclude_tables()),
variable_get("backup_migrate_nodata_tables", _backup_migrate_default_structure_only_tables()),
'sql',
"save",
variable_get("backup_migrate_compression", "none"),
"scheduled",
variable_get("backup_migrate_timestamp_format", 'Y-m-d\TH-i-s')
);
// Set the timestamp to indecate last backup time.
variable_set("backup_migrate_schedule_last_backup", $now);
// Delete older backups if needed.
_backup_migrate_remove_expired_backups();
}
}
// Delete temp files abandoned for 6 or more hours.
foreach (file_scan_directory(file_directory_temp(), 'backup_migrate_*', array('.', '..'), 0, FALSE) as $file) {
if (filectime($file->filename) < time() - 21600) {
unlink($file->filename);
}
}
}
/**
* Implementation of hook_exit().
*/
function backup_migrate_exit() {
// Delete any temporary files generated during this execution.
_backup_migrate_temp_file('', TRUE);
}
/**
* Implementation of hook_perm().
*/
function backup_migrate_perm() {
return array('perform backup', 'access backup files', 'delete backup files', 'restore from backup');
}
/**
* Menu callback. Delete a previous backup.
*/
function _backup_migrate_delete() {
// Merge remainder of arguments from GET['q'], into relative file path.
$args = func_get_args();
$path = implode('/', $args);
if ($path && _backup_migrate_path_is_in_save_dir($path)) {
return drupal_get_form('backup_migrate_delete_confirm', $path);
}
$form_state['redirect'] = user_access('access backup files') ? "admin/content/backup_migrate/files" : "admin/content/backup_migrate";
}
/**
* Ask confirmation for file deletion.
*/
function backup_migrate_delete_confirm(&$form_state, $path) {
$form['path'] = array('#type' => 'value', '#value' => $path);
return confirm_form($form, t('Are you sure you want to delete the backup file at %path?', array('%path' => $path)), 'admin/content/backup_migrate/files', t('This action cannot be undone.'), t('Delete'), t('Cancel'));
}
function backup_migrate_delete_confirm_submit($form, &$form_state) {
$path = $form_state['values']['path'];
if ($path && _backup_migrate_path_is_in_save_dir($path)) {
file_delete($path);
}
watchdog('backup_migrate', 'Database backup file deleted: %file', array('%file' => $path));
$form_state['redirect'] = user_access('access backup files') ? "admin/content/backup_migrate/files" : "admin/content/backup_migrate";
}
/**
* The schedule form.
*/
function backup_migrate_schedule() {
$form = array();
$form['backup_migrate_schedule_backup_period'] = array(
"#type" => "textfield",
"#title" => t("Backup every"),
"#field_suffix" => t("Hour(s)"),
"#description" => t("Use 0 for no scheduled backup. Cron must be configured to run for backups to work."),
"#default_value" => variable_get("backup_migrate_schedule_backup_period", 0),
);
$form['backup_migrate_schedule_backup_keep'] = array(
"#type" => "textfield",
"#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"),
"#default_value" => variable_get("backup_migrate_schedule_backup_keep", 0),
);
if (!_backup_migrate_check_destination_dir('scheduled')) {
$form['backup_migrate_schedule_backup_period']['#disabled'] = TRUE;
$form['backup_migrate_schedule_backup_keep']['#disabled'] = TRUE;
}
return system_settings_form($form);
}
/**
* The backup/export form.
*/
function backup_migrate_backup() {
$form = array();
$tables = _backup_migrate_get_table_names();
$form['backup_migrate_exclude_tables'] = array(
"#type" => "select",
"#multiple" => TRUE,
"#title" => t("Exclude the following tables altogether"),
"#options" => $tables,
"#default_value" => variable_get("backup_migrate_exclude_tables", _backup_migrate_default_exclude_tables()),
"#description" => t("The selected tables will not be added to the backup file."),
);
$form['backup_migrate_nodata_tables'] = array(
"#type" => "select",
"#multiple" => TRUE,
"#title" => t("Exclude the data from the following tables"),
"#options" => $tables,
"#default_value" => variable_get("backup_migrate_nodata_tables", _backup_migrate_default_structure_only_tables()),
"#description" => t("The selected tables will have their structure backed up but not their contents. This is useful for excluding cache data to reduce file size."),
);
$form['backup_migrate_file_name'] = array(
"#type" => "textfield",
"#title" => t("Backup file name"),
"#default_value" => variable_get("backup_migrate_file_name", _backup_migrate_default_file_name()),
);
if (module_exists('token')) {
$form['token_help'] = array(
'#title' => t('Replacement patterns'),
'#type' => 'fieldset',
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#description' => t('Prefer raw-text replacements for text to avoid problems with HTML entities!'),
);
$form['token_help']['help'] = array(
'#value' => theme('token_help', ''),
);
}
$compression_options = array("none" => t("No Compression"));
if (@function_exists("gzencode")) {
$compression_options['gzip'] = t("GZip");
}
if (@function_exists("bzcompress")) {
$compression_options['bzip'] = t("BZip");
}
if (class_exists('ZipArchive')) {
$compression_options['zip'] = t("Zip");
}
$form['backup_migrate_compression'] = array(
"#type" => "radios",
"#title" => t("Compression"),
"#options" => $compression_options,
"#default_value" => variable_get("backup_migrate_compression", "none"),
);
$destination_options = array(
"download" => t("Download"),
);
if (_backup_migrate_check_destination_dir('manual')) {
$destination_options['save'] = t("Save to Files Directory");
}
$form['backup_migrate_destination'] = array(
"#type" => "radios",
"#title" => t("Destination"),
"#options" => $destination_options,
"#default_value" => variable_get("backup_migrate_destination", "download"),
);
$form['backup_migrate_append_timestamp'] = array(
"#type" => "checkbox",
"#title" => t("Append a timestamp."),
"#default_value" => variable_get("backup_migrate_append_timestamp", 1),
);
$form['backup_migrate_timestamp_format'] = array(
"#type" => "textfield",
"#title" => t("Timestamp format"),
"#default_value" => variable_get("backup_migrate_timestamp_format", 'Y-m-d\TH-i-s'),
"#description" => t('Should be a PHP <a href="!url">date()</a> format string.', array('!url' => 'http://www.php.net/date')),
);
$form['backup_migrate_save_settings'] = array(
"#type" => "checkbox",
"#title" => t("Save these settings."),
"#default_value" => 1,
);
$form[] = array(
'#type' => 'submit',
'#value' => t('Backup Database'),
);
return $form;
}
/**
* Submit the form. Save the values as defaults if desired and output the backup file.
*/
function backup_migrate_backup_submit($form, &$form_state) {
if ($form_state['values']['backup_migrate_save_settings']) {
variable_set("backup_migrate_exclude_tables", $form_state['values']['backup_migrate_exclude_tables']);
variable_set("backup_migrate_nodata_tables", $form_state['values']['backup_migrate_nodata_tables']);
variable_set("backup_migrate_file_name", $form_state['values']['backup_migrate_file_name']);
variable_set("backup_migrate_destination", $form_state['values']['backup_migrate_destination']);
variable_set("backup_migrate_compression", $form_state['values']['backup_migrate_compression']);
variable_set("backup_migrate_append_timestamp", $form_state['values']['backup_migrate_append_timestamp']);
variable_set("backup_migrate_timestamp_format", $form_state['values']['backup_migrate_timestamp_format']);
}
$out = _backup_migrate_dump_tables(
$form_state['values']['backup_migrate_file_name'],
$form_state['values']['backup_migrate_exclude_tables'],
$form_state['values']['backup_migrate_nodata_tables'],
'sql',
$form_state['values']['backup_migrate_destination'],
$form_state['values']['backup_migrate_compression'],
"manual",
$form_state['values']['backup_migrate_append_timestamp'] ? $form_state['values']['backup_migrate_timestamp_format'] : FALSE
);
$form_state['redirect'] = $out;
}
/**
* Restore a backup file (from the server)
*/
function _backup_migrate_restore_from_server() {
// Merge remainder of arguments from GET['q'], into relative file path.
$args = func_get_args();
$path = implode('/', $args);
if ($path && _backup_migrate_path_is_in_save_dir($path)) {
return drupal_get_form('backup_migrate_restore_confirm', $path);
}
drupal_goto(user_access('access backup files') ? "admin/content/backup_migrate/files" : "admin/content/backup_migrate");
}
/**
* Ask confirmation for file restore.
*/
function backup_migrate_restore_confirm(&$form_state, $path) {
$form['path'] = array('#type' => 'value', '#value' => $path);
return confirm_form($form, t('Are you sure you want to restore the database from the backup at %path?', array('%path' => $path)), 'admin/content/backup_migrate/files', t('This will delete some or all of your data and cannot be undone. <strong>Always test your backups on a non-production server!</strong>'), t('Restore'), t('Cancel'));
}
function backup_migrate_restore_confirm_submit($form, &$form_state) {
$path = $form_state['values']['path'];
if ($path && _backup_migrate_path_is_in_save_dir($path)) {
_backup_migrate_restore_file($path);
watchdog('backup_migrate', 'Database restored from %file', array('%file' => $path));
}
$form_state['redirect'] = user_access('access backup files') ? "admin/content/backup_migrate/files" : "admin/content/backup_migrate";
}
/**
* The restore/import upload form.
*/
function backup_migrate_restore() {
$form = array();
$form['backup_migrate_restore_upload'] = array(
'#title' => t('Upload a Backup File'),
'#type' => 'file',
'#description' => t("Upload a backup file created by this version of this module. For other database backups please use another tool for import. Max file size: %size", array("%size" => format_size(file_upload_max_size()))),
);
$form[] = array(
'#type' => 'markup',
'#value' => t('<p>This will delete some or all of your data and cannot be undone. If there is a sessions table in the backup file, you and all other currently logged in users will be logged out. <strong>Always test your backups on a non-production server!</strong></p>'),
);
$form[] = array(
'#type' => 'submit',
'#value' => t('Restore Database'),
);
if (user_access('access backup files')) {
$form[] = array(
'#type' => 'markup',
'#value' => t('<p>Or you can restore one of the files in the <a href="!url">saved backup directory.</a></p>', array("!url" => url("admin/content/backup_migrate/files"))),
);
}
$form['#attributes'] = array('enctype' => 'multipart/form-data');
return $form;
}
/**
* The restore submit. Do the restore.
*/
function backup_migrate_restore_submit($form, &$form_state) {
if ($file = file_save_upload('backup_migrate_restore_upload')) {
_backup_migrate_restore_file($file->filepath, $file->filename, TRUE);
watchdog('backup_migrate', 'Database restored from upload %file', array('%file' => $file->filename));
}
$form_state['redirect'] = 'admin/content/backup_migrate/restore';
}
/**
* Action to backup the drupal site. Requires actions.module.
*/
function action_backup_migrate_backup($op, $edit = array()) {
switch ($op) {
case 'do':
_backup_migrate_backup_with_defaults();
watchdog('action', 'Backed up database');
break;
case 'metadata':
return array(
'description' => t('Backup the database with the default settings'),
'type' => t('Backup and Migrate'),
'batchable' => TRUE,
'configurable' => FALSE,
);
// Return an HTML config form for the action.
case 'form':
return '';
// Validate the HTML form.
case 'validate':
return TRUE;
// Process the HTML form to store configuration.
case 'submit':
return '';
}
}
/*
* Implementation of hook_action_info().
*/
function backup_migrate_action_info() {
return array(
'backup_migrate_backup_action' => array(
'description' => t('Backup the database with the default settings'),
'configurable' => FALSE,
'hooks' => array('any' => TRUE),
'type' => 'system',
),
);
}
/*
* Action callback.
*/
function backup_migrate_backup_action() {
_backup_migrate_backup_with_defaults();
}
/**
* Backup the database with the default settings.
*/
function _backup_migrate_backup_with_defaults($mode = "manual") {
_backup_migrate_dump_tables(
variable_get("backup_migrate_file_name", _backup_migrate_default_file_name()),
variable_get("backup_migrate_exclude_tables", _backup_migrate_default_exclude_tables()),
variable_get("backup_migrate_nodata_tables", _backup_migrate_default_structure_only_tables()),
'sql',
'save',
variable_get("backup_migrate_compression", "none"),
$mode,
variable_get("backup_migrate_append_timestamp", 1) ? variable_get("backup_migrate_timestamp_format", 'Y-m-d\TH-i-s') : FALSE
);
}
/**
* Build the database dump file. Takes a list of tables to exclude and some formatting options.
*/
function _backup_migrate_dump_tables($filename, $exclude_tables, $nodata_tables, $type = "sql", $destination = "download", $compression = "none", $mode = "manual", $append_timestamp = FALSE) {
$file_mime = "text/plain";
$success = FALSE;
if ($append_timestamp) {
$filename .= "-". date($append_timestamp);
}
$filename = _backup_migrate_clean_filename($filename);
// Dump the database.
$temp_file = _backup_migrate_temp_file();
switch ($type) {
case "sql":
$success = _backup_migrate_get_dump_sql($temp_file, $exclude_tables, $nodata_tables);
$filename .= ".sql";
$filemime = 'text/x-sql';
break;
}
// Compress the results.
if ($success) {
switch ($compression) {
case "gzip":
$temp_gz = _backup_migrate_temp_file('gz');
if ($success = _backup_migrate_gzip_encode($temp_file, $temp_gz, 9)) {
$temp_file = $temp_gz;
$filename .= ".gz";
$filemime = 'application/x-gzip';
}
break;
case "bzip":
$temp_bz = _backup_migrate_temp_file('bz');
if ($success = _backup_migrate_bzip_encode($temp_file, $temp_bz)) {
$temp_file = $temp_bz;
$filename .= ".bz";
$filemime = 'application/x-bzip';
}
break;
case "zip":
$temp_zip = _backup_migrate_temp_file('zip');
if ($success = _backup_migrate_zip_encode($temp_file, $temp_zip, $filename)) {
$temp_file = $temp_zip;
$filename .= ".zip";
$filemime = 'application/zip';
}
break;
}
}
// Save or download the results.
if ($success) {
switch ($destination) {
case "save":
_backup_migrate_save_to_disk($temp_file, $filename, $mode);
break;
case "download":
_backup_migrate_send_file_to_download($filename, $file_mime, $temp_file);
break;
}
}
// Delete any temporary files we've created.
_backup_migrate_temp_file("", TRUE);
}
/**
* Force a browser download for the file.
*/
function _backup_migrate_send_file_to_download($filename, $filetype, $file_path) {
header('Content-Type: '. $filetype);
header('Expires: '. gmdate('D, d M Y H:i:s') .' GMT');
header('Content-Length: '. filesize($file_path));
header('Content-Disposition: attachment; filename="'. $filename .'"');
// Transfer file in 1024 byte chunks to save memory usage.
if ($fd = fopen($file_path, 'rb')) {
while (!feof($fd)) {
print fread($fd, 1024);
}
fclose($fd);
}
// Delete any temporary files we've created.
_backup_migrate_temp_file("", TRUE);
watchdog('backup_migrate', 'Database backup downloaded');
module_invoke_all('exit');
exit();
}
/**
* Get the sql dump file. Returns a list of sql commands, one command per line.
* That makes it easier to import without loading the whole file into memory.
* The files are a little harder to read, but human-readability is not a priority
*/
function _backup_migrate_get_dump_sql($file, $exclude_tables, $nodata_tables) {
if ($dst = fopen($file, "w")) {
$exclude = variable_get("backup_migrate_exclude_tables", _backup_migrate_default_exclude_tables());
$nodata = variable_get("backup_migrate_nodata_tables", _backup_migrate_default_structure_only_tables());
fwrite($dst, _backup_migrate_get_sql_file_header());
$alltables = _backup_migrate_get_tables();
foreach ($alltables as $table) {
if ($table['Name'] && !isset($exclude[$table['Name']])) {
fwrite($dst, _backup_migrate_get_table_structure_sql($table));
if (!in_array($table['Name'], $nodata)) {
_backup_migrate_dump_table_data_sql_to_handle($dst, $table);
}
}
}
fwrite($dst, _backup_migrate_get_sql_file_footer());
fclose($dst);
return TRUE;
}
else {
return FALSE;
}
}
/**
* Get the sql for the structure of the given table.
*/
function _backup_migrate_get_table_structure_sql($table) {
$out = "";
$result = db_query("SHOW CREATE TABLE `". $table['Name'] ."`");
if ($create = db_fetch_array($result)) {
$out .= "DROP TABLE IF EXISTS `". $table['Name'] ."`;\n";
$out .= strtr($create['Create Table'], "\n", " ");
if ($table['Auto_increment']) {
$out .= " AUTO_INCREMENT=". $table['Auto_increment'];
}
$out .= ";\n";
}
return $out;
}
/**
* Get the sql to insert the data for a given table
*/
function _backup_migrate_dump_table_data_sql_to_handle($dst, $table) {
$data = db_query("SELECT * FROM `". $table['Name'] ."`");
while ($row = db_fetch_array($data)) {
$items = array();
foreach ($row as $key => $value) {
$items[] = is_null($value) ? "null" : "'". db_escape_string($value) ."'";
}
if ($items) {
fwrite(
$dst,
"INSERT INTO `". $table['Name'] ."` VALUES (". implode(",", $items) .");\n"
);
}
}
}
/**
* The header for the top of the sql dump file. These commands set the connection
* character encoding to help prevent encoding conversion issues.
*/
function _backup_migrate_get_sql_file_header() {
return "
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE=NO_AUTO_VALUE_ON_ZERO */;
SET NAMES utf8;
";
}
/**
* The footer of the sql dump file.
*/
function _backup_migrate_get_sql_file_footer() {
return "
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
";
}
/**
* Get a list of tables in the db. Works with MySQL, Postgres not tested.
*/
function _backup_migrate_get_tables() {
$out = "";
// get auto_increment values and names of all tables
$tables = db_query("show table status");
while ($table = db_fetch_array($tables)) {
$out[$table['Name']] = $table;
}
return $out;
}
/**
* Get the list of table names.
*/
function _backup_migrate_get_table_names() {
$out = "";
// Get auto_increment values and names of all tables.
$tables = db_query("show table status");
while ($table = db_fetch_array($tables)) {
$out[$table['Name']] = $table['Name'];
}
return $out;
}
/**
* Restore from a previously backed up files. Accepts any file created by the backup function.
*/
function _backup_migrate_restore_file($filepath, $filename = "", $delete = FALSE) {
if (!$filename) {
$filename = $filepath;
}
$file_is_temp = $delete;
$open_func = "fopen";
$read_func = "fgets";
$close_func = "fclose";
// figure out if the file is compressed by the file extention
if (drupal_substr($filename, -4, 4) == ".sql") {
// No compression.
}
if (drupal_substr($filename, -3, 3) == ".gz") {
if (function_exists("gzopen")) {
$open_func = "gzopen";
$read_func = "gzgets";
$close_func = "gzclose";
}
else {
// GZip compression... not supported.
drupal_set_message(t("This version of PHP does not support gzip comressed files. Please try using an uncompressed sql backup."), 'error');
drupal_goto("admin/content/backup_migrate/restore");
}
}
// BZip compression.
if (drupal_substr($filename, -3, 3) == ".bz") {
if (function_exists("bzopen")) {
$open_func = "fopen";
$read_func = "fgets";
// Decompress the file to a temp file.
$tmp = tempnam(file_directory_temp(), 'tmp_');
if (($dst = fopen($tmp, "w")) && ($src = bzopen($filepath, "r"))) {
while ($data = bzread($src)) {
fwrite($dst, $data);
}
fclose($dst);
bzclose($src);
if ($delete) {
unlink($filepath);
}
$filepath = $tmp;
$delete = TRUE;
}
else {
drupal_set_message(t("Unable to decompress bzip file. Please try using an uncompressed backup."), 'error');
drupal_goto("admin/content/backup_migrate/restore");
}
}
else {
// BZip compression... not supported.
drupal_set_message(t("This version of PHP does not support bzip compressed files. Please try using an uncompressed backup."), 'error');
drupal_goto("admin/content/backup_migrate/restore");
}
}
// Zip compression.
if (drupal_substr($filename, -4, 4) == ".zip") {
if (class_exists('ZipArchive')) {
if ($filepath != $filename) {
rename($filepath, $filepath .".zip");
$filepath .= ".zip";
}
$tmp = tempnam(file_directory_temp(), 'tmp_');
$zip = new ZipArchive;
if (($dst = fopen($tmp, "w")) && ($src = $zip->open($filepath))) {
if ($data = $zip->getFromIndex(0)) {
fwrite($dst, $data);
}
fclose($dst);
$zip->close();
if ($delete) {
unlink($filepath);
}
$filepath = $tmp;
$delete = TRUE;
}
else {
drupal_set_message(t("Unable to decompress zip file. Please try using an uncompressed backup."), 'error');
drupal_goto("admin/content/backup_migrate/restore");
}
}
else {
// Zip compression... not supported.
drupal_set_message(t("This version of PHP does not support zip comressed files. Please try using an uncompressed backup."), 'error');
drupal_goto("admin/content/backup_migrate/restore");
}
}
// Open the file (with fopen or gzopen depending on file format).
if ($handle = @$open_func($filepath, "r")) {
$num = 0;
// Read one line at a time and run the query.
while ($line = $read_func($handle)) {
$line = trim($line);
if ($line) {
// Use the helper instead of the api function to avoid substitution of '{' etc.
_db_query($line);
$num++;
}
}
// Close the file with fclose/gzclose.
$close_func($handle);
// Delete the file if it is temporary.
if ($delete) {
unlink($filepath);
}
$message = t("Restore complete. %num SQL commands executed.", array("%num" => $num));
$message .= $file_is_temp ? "" : "(". l(t("Restore Again..."), "admin/content/backup_migrate/restorefile/". $filepath) .")";
drupal_set_message($message);
}
else {
drupal_set_message(t("Unable to open file %file to restore database", array("%file" => $filepath)), 'error');
}
// Delete any temp files we've created.
_backup_migrate_temp_file("", TRUE);
}
/*
Backup File Management
*/
/**
* Return a list of backup filetypes.
*/
function _backup_migrate_filetypes() {
return array(
"sql" => array(
"extension" => ".sql",
"filemime" => "text/x-sql",
),
"gzip" => array(
"extension" => ".gz",
"filemime" => "application/x-gzip",
),
"bzip" => array(
"extension" => ".bz",
"filemime" => "application/x-bzip",
),
"zip" => array(
"extension" => ".zip",
"filemime" => "application/zip",
),
);
}
/**
* Get the basic info for a backup file on the server.
*/
function _backup_migrate_file_info($path) {
$types = _backup_migrate_filetypes();
foreach ($types as $type) {
$extlen = drupal_strlen($type['extension']);
if (drupal_substr($path, -$extlen, $extlen) === $type['extension']) {
$out = $type;
$out['filesize'] = filesize($path);
$out['filename'] = basename($path);
$out['filemtime'] = filemtime($path);
$out['filectime'] = filectime($path);
$out['filepath'] = $path;
return $out;
}
}
return NULL;
}
/**
* Save the backup file to the appropriete folder on the server.
*/
function _backup_migrate_save_to_disk($temp_file, $filename, $mode = "manual") {
if ($dir = _backup_migrate_check_destination_dir($mode)) {
$filepath = $dir ."/". $filename;
rename($temp_file, $filepath);
$message = t('Database backup saved to %file. ', array('%file' => $filepath));
watchdog('backup_migrate', $message);
if ($mode == "manual" && user_access('perform backup')) {
$message .= user_access("access backup files") ? "(". l(t("Download"), "system/files/". $filepath) .") " : "";
$message .= user_access("delete backup files") ? "(". l(t("Delete..."), "admin/content/backup_migrate/delete/". $filepath) .") " : "";
$message .= user_access("restore from backup") ? "(". l(t("Restore..."), "admin/content/backup_migrate/restorefile/". $filepath) .")" : "";
drupal_set_message($message);
}
}
}
/**
* Implementation of hook_file_download.()
*
* Allow users with the appropriate permissions to download backup files.
*/
function backup_migrate_file_download($path) {
if (_backup_migrate_path_is_in_save_dir($path)) {
if (user_access('access backup files') && $info = _backup_migrate_file_info($path)) {
return array(
'Content-Type: '. $info['filemime'],
'Content-Length: '. $info['filesize'],
'Content-Disposition: attachment; filename="'. $info['filename'] .'"',
);
}
else {
return -1;
}
}
return NULL;
}
/**
* Get a temp file. Store it in the normal save path for slightly better security
* in shared environments.
*/
function _backup_migrate_temp_file($extension = "", $delete_all = FALSE) {
static $files = array();
if ($delete_all) {
_backup_migrate_temp_files_delete($files);
}
else {
$file = tempnam(file_directory_temp(), 'backup_migrate_');
if (!empty($extension)) {
unlink($file);
$file .= '.'. $extension;
}
$files[] = $file;
return $file;
}
}
/**
* Delete all temporary files.
*/
function _backup_migrate_temp_files_delete($files) {
foreach ($files as $file) {
if (file_exists($file)) {
@unlink($file);
}
}
}
/**
* List the previously created backup files.
*/
function _backup_migrate_list_files($mode = "manual") {
$files = array();
if ($dir = _backup_migrate_check_destination_dir($mode)) {
if ($handle = opendir($dir)) {
while (FALSE !== ($file = readdir($handle))) {
$filepath = $dir ."/". $file;
if ($info = _backup_migrate_file_info($filepath)) {
$files[$file] = array(
$file,
format_date($info['filemtime']),
format_size($info['filesize']),
l(t("Download"), "system/files/". $filepath),
user_access('restore from backup') ? l(t("Restore"), "admin/content/backup_migrate/restorefile/". $filepath) : '',
user_access('delete backup files') ? l(t("Delete"), "admin/content/backup_migrate/delete/". $filepath) : '',
);
}
}
}
}
krsort($files);
return theme("table", array(), $files);
}
/**
* Remove older backups keeping only the number specified by the aministrator.
*/
function _backup_migrate_remove_expired_backups() {
$num_to_keep = variable_get("backup_migrate_schedule_backup_keep", 0);
// If num to keep is not 0 (0 is infinity).
if ($num_to_keep && $dir = _backup_migrate_check_destination_dir("scheduled")) {
// Create a list of backup files indexed by time (with an aditional index to
// prevent two files with the same create time from overwriting each other).
$res = opendir($dir);
$files = array();
$i = 0;
if ($res) {
// Read all files and sort them by modified time.
while ($file = readdir($res)) {
$filepath = $dir ."/". $file;
if ($info = _backup_migrate_file_info($filepath)) {
$files[str_pad($info['filemtime'], 10, "0", STR_PAD_LEFT) ."-". $i++] = $filepath;
}
}
}
// 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++) {
$filepath = array_shift($files);
file_delete($filepath);
}
}
}
}
/**
* Return the path on the server to save the dump files.
*/
function _backup_migrate_path_is_in_save_dir($path, $mode = "") {
$backup_dir = _backup_migrate_get_save_path($mode);
return file_exists($backup_dir) && file_check_location($path, $backup_dir);
}
/**
* Return the path on the server to save the dump files.
*/
function _backup_migrate_get_save_path($mode = "") {
$dir = file_directory_path() ."/backup_migrate";
if ($mode) {
$dir .= $mode == "manual" ? "/manual" : "/scheduled";
}
return $dir;
}
/**
* Prepare the destination directory for the backups.
*/
function _backup_migrate_check_destination_dir($mode = "") {
$directory = _backup_migrate_get_save_path();
$out = $subdir = rtrim($directory ."/". $mode, "/");
// Check for the main directory.
if (!file_check_directory($directory, TRUE)) {
// unable to create main directory
$message = t("Unable to create or write to the save directory '%directory'. Please check the file permissions on your files directory.", array('%directory' => $directory));
drupal_set_message($message, "error");
return FALSE;
}
// Create subdir if needed.
if (($subdir != $directory) && !file_check_directory($subdir, TRUE)) {
// Unable to create sub directory.
$message = t("Unable to create or write to the save directory '%directory'. Please check the file permissions on your files directory.", array('%directory' => $subdir));
drupal_set_message($message, "error");
return FALSE;
}
// Check for a htaccess file which adequately protects the backup files.
$htaccess_lines = "order allow,deny\ndeny from all\n";
if (!is_file($directory .'/.htaccess') || strpos(file_get_contents($directory .'/.htaccess'), $htaccess_lines) === FALSE) {
// Attempt to protect the backup files from public access using htaccess.
if (($fp = @fopen($directory .'/.htaccess', 'w')) && @fputs($fp, $htaccess_lines)) {
fclose($fp);
chmod($directory .'/.htaccess', 0664);
}
// Unable to create htaccess... warn the user.
else {
$message = "Security warning: Couldn't modify .htaccess file. Please create a .htaccess file in your %directory directory which contains the following lines: <code>!htaccess
$replace = array('%directory' => $directory, '!htaccess' => '
'. nl2br(check_plain($htaccess_lines)));
drupal_set_message(t($message, $replace), "error");
watchdog('security', $message, $replace, WATCHDOG_ERROR);
return FALSE;
}
}
// Check the user agent to make sure we're not responding to a request from drupal itself.
// That should prevent infinite loops which could be caused by poormanscron in some circumstances.
if (strpos($_SERVER['HTTP_USER_AGENT'], 'Drupal') !== FALSE) {
return FALSE;
}
// Check to see if the destination is publicly accessible
$test_contents = "this file should not be publicly accesible";
// Create the the text.txt file if it's not already there.
if (!is_file($subdir .'/test.txt') || file_get_contents($subdir .'/test.txt') != $test_contents) {
if ($fp = fopen($subdir .'/test.txt', 'w')) {
@fputs($fp, $test_contents);
fclose($fp);
}
else {
$message = t("Security notice: Backup and Migrate was unable to write a test text file to the destination directory %directory, and is therefore unable to check the security of the backup destination. Backups to the server will be disabled until the destination becomes writable and secure.", array('%directory' => $directory));
drupal_set_message($message, "error");
return FALSE;
}
}
// Attempt to read the test file via http. This may fail for other reasons, so it's not a bullet-proof check.
$path = trim(substr($subdir .'/test.txt', strlen(file_directory_path())), '\\/');
if (_backup_migrate_test_file_readable_remotely($path, $contents)) {
$message = t("Security notice: Backup and Migrate will not save backup files to the server because the destination directory is publicly accessible. If you want to save files to the server, please secure the '%directory' directory", array('%directory' => $directory));
drupal_set_message($message, "error");
return FALSE;
}
return $out;
}
/**
* Check if a file can be read remotely via http.
*/
function _backup_migrate_test_file_readable_remotely($path, $contents) {
$url = $GLOBALS['base_url'] .'/'. file_directory_path() .'/'. str_replace('\\', '/', $path);
$result = drupal_http_request($url);
if (strpos($result->data, $contents) !== FALSE) {
return TRUE;
}
return FALSE;
}
/**
* Gzip encode a file.
*/
function _backup_migrate_gzip_encode($source, $dest, $level = 9) {
$success = FALSE;
if (@function_exists("gzopen")) {
if (($fp_out = gzopen($dest, 'wb'. $level)) && ($fp_in = fopen($source, 'rb'))) {
while (!feof($fp_in)) {
gzwrite($fp_out, fread($fp_in, 1024 * 512));
}
$success = TRUE;
}
@fclose($fp_in);
@gzclose($fp_out);
}
return $success;
}
/**
* Bzip encode a file.
*/
function _backup_migrate_bzip_encode($source, $dest) {
$success = FALSE;
if (@function_exists("bzopen")) {
if (($fp_out = bzopen($dest, 'w')) && ($fp_in = fopen($source, 'rb'))) {
while (!feof($fp_in)) {
bzwrite($fp_out, fread($fp_in, 1024 * 512));
}
$success = TRUE;
}
else {
$error = TRUE;
}
@fclose($fp_in);
@bzclose($fp_out);
}
return $success;
}
/**
* Zip encode a file.
*/
function _backup_migrate_zip_encode($source, $dest, $filename) {
$success = FALSE;
if (class_exists('ZipArchive')) {
$zip = new ZipArchive;
$res = $zip->open($dest, constant("ZipArchive::CREATE"));
if ($res === TRUE) {
$zip->addFile($source, $filename);
$success = $zip->close();
}
}
return $success;
}
/*
Defaults
*/
/**
* Construct a default filename using the site's name.
*/
function _backup_migrate_default_file_name() {
if (module_exists('token')) {
return '[site-name]';
}
else {
return _backup_migrate_clean_filename(variable_get('site_name', "backup_migrate"));
}
}
/**
* Construct a default filename using token and some cleaning.
*/
function _backup_migrate_clean_filename($filename) {
if (module_exists('token') && function_exists('token_replace')) {
$filename = token_replace($filename, 'global');
}
$filename = preg_replace("/[^a-zA-Z0-9\.\-_]/", "", $filename);
if (strlen($filename) > 50) {
$filename = drupal_substr($filename, 0, 50);
}
if (strlen($filename) == 0) {
$filename = 'untitled';
}
return $filename;
}
/**
* Tables to ingore altogether. None by default.
*/
function _backup_migrate_default_exclude_tables() {
return array();
}
/**
* Return the default tables whose data can be ignored. These tables mostly contain
* info which can be easily reproducted (such as cache or search index)
* but also tables which can become quite bloated but are not necessarily extremely
* important to back up or migrate during development (such ass access log and watchdog)
*/
function _backup_migrate_default_structure_only_tables() {
$core = array(
'cache',
'cache_filter',
'cache_calendar_ical',
'cache_menu',
'cache_page',
'cache_views',
'sessions',
'search_dataset',
'search_index',
'search_keywords_log',
'search_total',
'watchdog',
'accesslog',
'devel_queries',
'devel_times',
);
$alltables = array_merge($core, module_invoke_all('devel_caches'));
global $db_prefix;
foreach ($alltables as $table) {
$prefixed_tables[] = $db_prefix . $table;
}
return $prefixed_tables;
}