<?php
/* ==========================================================================
	backupDB v0.3
	MySQL database backup using PHP
	copyright (c) 2013-2014 by Andreas Thul
	-------------------------------------------------------------------------
	main file: backupDB.php
	-------------------------------------------------------------------------
	idea and some code taken from WordPress plugin 'wp-dbmanager'
	-------------------------------------------------------------------------
	2013-05-29: initial release
	2013-10-26: added description for backup set,
				added option to ignore single table
	2013-05-27: ignore-table now accepts multiple tables
========================================================================== */

// function taken from http://php.net/manual/de/function.filesize.php

function human_filesize($bytes, $decimals = 2) {

	$sz = 'BKMGTP';
	$factor = floor((strlen($bytes) - 1) / 3);
	return sprintf("%.{$decimals}f", $bytes / pow(1024, $factor)) . @$sz[$factor];
}

function mailFile($email, $description, $database, $filename, $filepath) {

	$filesize = filesize($filepath);

	$file = fopen($filepath, 'rb');
	$file_data = fread($file, filesize($filepath));
	fclose($file);

	$file_data = chunk_split(base64_encode($file_data));

	$mail_subject = $description;
	$mail_header = "From: <$email>";

	$random_time = md5(time());
	$mime_boundary = "==WP-DBManager- $random_time";

	$mail_header .= "\nMIME-Version: 1.0\n" .
		"Content-Type: multipart/mixed;\n" .
		" boundary=\"{$mime_boundary}\"";

	$mail_message = "backupDB dump of '$database'\n";
	$mail_message .= "  attached as '$filename'\n";
	$mail_message .= "  filesize " . human_filesize($filesize) . "\n";

	$mail_message = "This is a multi-part message in MIME format.\n\n" .
		"--{$mime_boundary}\n" .
		"Content-Type: text/plain; charset=\"utf-8\"\n" .
		"Content-Transfer-Encoding: 7bit\n\n" . $mail_message . "\n\n";
	$mail_message .= "--{$mime_boundary}\n" .
		"Content-Type: application/octet-stream;\n" .
		" name=\"{$filename}\"\n" .
		"Content-Disposition: attachment;\n" .
		" filename=\"{$filename}\"\n" .
		"Content-Transfer-Encoding: base64\n\n" .
		$file_data . "\n\n--{$mime_boundary}--\n";

	mail($email, $mail_subject, $mail_message, $mail_header);
}

function addLog($text) {

	global $log;

	fwrite($log, '[' . date('Y-m-d H:i:s') . '] ' . "$text\n");
}

// include the user configuration
require_once(dirname(__FILE__) . '/config.php');

// open logfile
$log = fopen($backup['log'], 'a');
addLog('--- backupDB start');

// basic settings
$backup['mysqldump'] = @exec('which mysqldump');
$backup['preflight_ok'] = 1;

// preflight checks
if(!is_writable($backup['path'])) {
	addLog('path ' . $backup['path'] . 'is not writable, aborting');
	$backup['preflight_ok'] = 0;
}
if(!preg_match('/mysqldump/', $backup['mysqldump'])) {
	addLog('could not locate mysqldump, aborting');
	$backup['preflight_ok'] = 0;
}

if($backup['preflight_ok']) {

	addLog('preflight ok, starting backup');

	foreach ($backup['todo'] as $todo) {

		addLog("preparing backup of '$todo[database]' on host '$todo[host]'");

		$backup['timestamp'] = date('Y-m-d_H-i-s');
		$backup['filename'] = $backup['timestamp'] . '_' . $todo['database'] . '.sql.gz';
		$backup['filepath'] = $backup['path'] . '/' . $backup['filename'];

		$backup['command'] = $backup['mysqldump'] . ' --force --host="' . $todo['host'] .'" --user="' . $todo['user'] . '" --password="' . $todo['password'] . '" --add-drop-table --skip-lock-tables ';

		if (strlen($todo['ignore-table'])) {

			$tables_to_ignore = preg_split('/,/', $todo['ignore-table']);

			foreach ($tables_to_ignore as $table_to_ignore) {

				$backup['command'] .= '--ignore-table=' . $todo['database'] . '.' . $table_to_ignore . ' ';
			}


		}

		$backup['command'] .= $todo['database'] . ' | gzip > ' . $backup['filepath'];

		addlog("backup will be written to file '" . $backup['filepath'] . "'");

		passthru($backup['command'], $error);

		if (!$error) {

			addLog("mysqldump success, mailing file to '$backup[email]'");
			mailFile($backup['email'], $todo['description'], $todo['database'], $backup['filename'], $backup['filepath']);

			addLog('removing file');
			unlink($backup['filepath']);
		}
	}
}

addLog('--- backupDB end');

?>