phpMySQLAutoBackup  1.6.1
Open source - automates the backup of your MySQL database
 All Data Structures Files Functions Variables
phpmysqlautobackup_extras.php
Go to the documentation of this file.
1 <?php
2 /*******************************************************************************************
3  phpMySQLAutoBackup - Author: http://www.DWalker.co.uk - released under GPL License
4  For support and help please try the forum at: http://www.dwalker.co.uk/forum/
5 ********************************************************************************************
6 Version Date Comment
7 0.2.0 7th July 2005 GPL release
8 0.3.0 June 2006 Upgrade - added ability to backup separate tables
9 0.4.0 Dec 2006 removed bugs/improved code
10 1.4.0 Dec 2007 improved faster version
11 1.5.0 Dec 2008 improved and added FTP backup to remote site
12 1.5.4 Nov 2009 Version printed in email
13 1.5.5 Feb 2011 more options for config added - email reports only and/or backup, save backup file to local and/or remote server.
14  Reporter added: email report of last 6 (or more) backup stats (date, total bytes exported, total lines exported) plus any errors
15  MySQL error reporting added and Automated version checker added
16 1.6.0 Dec 2011 PDO version
17 1.6.1 April 2012 - CURLOPT_TRANSFERTEXT turned off (to stop garbaging zip file on transfer) and bug removed from write_back
18 ********************************************************************************************/
20 // ---------------------------------------------------------
21 function has_data($value)
22 {
23  if (is_array($value)) return (sizeof($value) > 0)? true : false;
24  else return (($value != '') && (strtolower($value) != 'null') && (strlen(trim($value)) > 0)) ? true : false;
25 }
26 
27 function xmail ($to_emailaddress,$from_emailaddress, $subject, $content, $file_name, $backup_type, $newline, $ver)
28 {
29  $mail_attached = "";
30  $boundary = "----=_NextPart_000_01FB_010".md5($to_emailaddress);
31  $mail_attached.="--".$boundary.$newline
32  ."Content-Type: application/octet-stream;$newline name=\"$file_name\"$newline"
33  ."Content-Transfer-Encoding: base64$newline"
34  ."Content-Disposition: attachment;$newline filename=\"$file_name\"$newline$newline"
35  .chunk_split(base64_encode($content)).$newline;
36  $mail_attached .= "--".$boundary."--$newline";
37  $add_header ="MIME-Version: 1.0".$newline."Content-Type: multipart/mixed;$newline boundary=\"$boundary\" $newline";
38  $mail_content="--".$boundary.$newline."Content-Type: text/plain; $newline charset=\"iso-8859-1\"$newline"."Content-Transfer-Encoding: 7bit$newline $newline BACKUP Successful...$newline $newline Please see attached for your zipped Backup file; $backup_type $newline If this is the first backup then you should test it restores correctly to a test server.$newline $newline phpMySQLAutoBackup (version $ver) is developed by http://www.dwalker.co.uk/ $newline $newline Have a good day now you have a backup of your MySQL db :-) $newline $newline Please consider making a donation at: $newline http://www.dwalker.co.uk/make_a_donation.php $newline (every penny or cent helps)$newline".$mail_attached;
39  return mail($to_emailaddress, $subject, $mail_content, "From: $from_emailaddress".$newline."Reply-To:$from_emailaddress".$newline.$add_header);
40 }
41 
42 function write_backup($gzdata, $backup_file_name)
43 {
44  $fp = fopen(LOCATION."../backups/".$backup_file_name, "w");
45  fwrite($fp, $gzdata);
46  fclose($fp);
47  //check folder is protected - stop HTTP access
48  if (!file_exists(LOCATION."../backups/.htaccess"))
49  {
50  $fp = fopen(LOCATION."../backups/.htaccess", "w");
51  fwrite($fp, "deny from all");
52  fclose($fp);
53  }
55 }
56 
58 {
59  $files=$keep=array();
60  $prefix = 'mysql_'.DBNAME;
61  $suffix = ".sql.gz";
62  $dir = LOCATION."../backups/";
63  if ($handle = opendir($dir))
64  {
65  while (false !== ($file = readdir($handle)))
66  {
67  if ((filetype($dir.$file) == "file") && (substr($file,0,strlen($prefix)) == $prefix) && (substr($file,-strlen($suffix)) == $suffix) && (filesize($dir.$file)>0))
68  {
69  $files[filemtime($dir.$file)]= $file;
70  }
71  }
72  closedir($handle);
73  krsort($files);
74  $slice = min(TOTAL_BACKUP_FILES_TO_RETAIN,sizeof($files));
75  if ($slice)
76  {
77  $erase = array_slice($files,TOTAL_BACKUP_FILES_TO_RETAIN);
78  foreach ($erase as $key=>$thisOne)
79  {
80  unlink($dir.$thisOne);
81  }
82  }
83  }
84 }
85 
86 
87 
89 {
90  public $error = "";
91  public function transfer_data($ftp_username,$ftp_password,$ftp_server,$ftp_path,$filename)
92  {
93  if (function_exists('curl_exec'))
94  {
95  $file=LOCATION."../backups/".$filename;
96  $fp = fopen($file, "r");
97  $ch = curl_init();
98  curl_setopt($ch, CURLOPT_URL, "ftp://$ftp_username:$ftp_password@$ftp_server.$ftp_path".$filename);
99  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
100  curl_setopt($ch, CURLOPT_UPLOAD, 1);
101  curl_setopt($ch, CURLOPT_INFILE, $fp);
102  curl_setopt($ch, CURLOPT_INFILESIZE, filesize($file));
103  curl_setopt($ch, CURLOPT_TRANSFERTEXT, 0);
104  curl_setopt($ch, CURLOPT_REFERER, $_SERVER['HTTP_HOST']." - via phpMySQLAutoBackup");
105  $output = curl_exec($ch);
106  $info = curl_getinfo($ch);
107  if (empty($info['http_code'])) $this->error = "\n\nFTP ERROR - Failed to transfer backup file to remote ftp server";
108  else
109  {
110  $http_codes = parse_ini_file(LOCATION."http_codes.ini");
111  if ($info['http_code']!=226) $this->error = "\n\nFTP ERROR - server response: \n".$info['http_code']
112  ." " . $http_codes[$info['http_code']]
113  ."\nfor more detail please refer to: http://www.w3.org/Protocols/rfc959/4_FileTransfer.html" ;
114  }
115  curl_close($ch);
116 
117  }
118  else $this->error = "\n\nWARNING: FTP will not function as PHP CURL does not exist on your hosting account - try a new host: http://www.seiretto.com";
119  return $this->error;
120  }
121 }
122 
123 
124 class record
125 {
126  public function save($date, $bytes, $lines)
127  {
128  $dbc = dbc::instance();
129  $result = $dbc->prepare("SHOW TABLES LIKE 'phpmysqlautobackup_log' ");
130  $rows = $dbc->executeGetRows($result);
131  if(count($rows)<1)
132  {
133  $q="CREATE TABLE IF NOT EXISTS `phpmysqlautobackup_log` (
134  `date` int(11) NOT NULL,
135  `bytes` int(11) NOT NULL,
136  `lines` int(11) NOT NULL,
137  PRIMARY KEY (`date`) )";
138  $result = $dbc->prepare($q);
139  $result = $dbc->execute($result);
140  }
141  $query="INSERT INTO `phpmysqlautobackup_log` (`date`, `bytes`, `lines`)
142  VALUES ('$date', '$bytes', '$lines')";
143  $result = $dbc->prepare($query);
144  $result = $dbc->execute($result);
145  $query="SELECT date FROM `phpmysqlautobackup_log` ORDER BY `date` DESC LIMIT 0 , ".LOG_REPORTS_MAX;
146  $result = $dbc->prepare($query);
147  $rows = $dbc->executeGetRows($result);
148 
149  $search_date=$rows[count($rows)-1]['date'];
150  $query="delete FROM `phpmysqlautobackup_log` where date<'$search_date' ";
151  $result = $dbc->prepare($query);
152  $result = $dbc->execute($result);
153  }
154 
155  public function get()
156  {
157  $dbc = dbc::instance();
158  $result = $dbc->prepare("SELECT * FROM `phpmysqlautobackup_log` ORDER BY `date` DESC ");
159  $rows = $dbc->executeGetRows($result);
160  $report="\nBelow are the records of the last ".LOG_REPORTS_MAX." backups.\nDATE and TIME (total bytes, Total lines exported)";
161  foreach ($rows as $row)
162  {
163  $report.= "\n".strftime("%d %b %Y - %H:%M:%S",$row['date'])." (";
164  $report.= number_format(($row['bytes']/1000), 2, '.', '') ." KB, ";
165  $report.= number_format($row['lines'])." lines)";
166  }
167  return $report;
168  }
169 
170 }
171 
172 class version
173 {
174  public function check($version)
175  {
176  $newest_version=$version;
177  if (function_exists('curl_exec'))
178  {
179  $ch = curl_init();
180  curl_setopt($ch, CURLOPT_URL, "http://www.dwalker.co.uk/versions/phpMySQLAutoBackup.php");
181  curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
182  $newest_version=curl_exec($ch);
183  curl_close($ch);
184  }
185  /*elseif ($fp = fsockopen("www.dwalker.co.uk", 80, $errno, $errstr, 30));
186  {
187  $headers ="GET /versions/phpMySQLAutoBackup.php HTTP/1.0\r\nHost: dwalker.co.uk\r\n"
188  . "Content-Type: application/x-www-form-urlencoded\r\n"
189  . "\r\nConnection: close\r\n\r\n";
190  fwrite($fp, $headers);
191  while (!feof($fp))
192  {
193  $newest_version= fgets($fp, 128);
194  }
195  fclose($fp);
196  } */
197  if ($version!=$newest_version) return "*WARNING: upgrade required! Please visit: http://www.dwalker.co.uk/phpmysqlautobackup/ ";
198  }
199 }
200 
201 class dbc extends PDO
202 {
203  protected static $instance;
204 
205  public function __construct()
206  {
207  $options = array(PDO::ATTR_PERSISTENT => true,PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION);
208  try {
209  $this->dbconn = new PDO(DBDRIVER.":host=".DBHOST.";port=".DBPORT.";dbname=".DBNAME,DBUSER,DBPASS,$options);
210  return $this->dbconn;
211  }
212  catch (PDOException $e){ $this->reportDBError($e->getMessage()); }
213  }
214 
215  public function reportDBError($msg)
216  {
217  if (DEBUG) print_r('<div style="padding:10%;"><h3>'.nl2br($msg).'</h3></div>');
218  else
219  {
220  if(!session_id()) session_start();
221  $_SESSION['pmab_mysql_errors'] = "\n\nMySQL error: ".$msg."\n";
222  }
223 
224  }
225 
226  public static function instance()
227  {
228  if (!isset(self::$instance)) self::$instance = new self();
229  return self::$instance;
230  }
231 
232  public function prepare($query) {
233  try { return $this->dbconn->prepare($query); }
234  catch (PDOException $e){ $this->reportDBError($e->getMessage()); }
235  }
236 
237  public function bindParam($query) {
238  try { return $this->dbconn->bindParam($query); }
239  catch (PDOException $e){ $this->reportDBError($e->getMessage()); }
240  }
241 
242  public function query($query) {
243  try {
244  if ($this->query($query)) return $this->fetchAll();
245  else return 0;
246  }
247  catch (PDOException $e){ $this->reportDBError($e->getMessage()."<hr>".$e->getTraceAsString()); } }
248 
249  public function execute($result) {//use for insert/update/delete
250  try { if ($result->execute()) return $result; }
251  catch (PDOException $e){ $this->reportDBError($e->getMessage()."<hr>".$e->getTraceAsString()); }
252  }
253  public function executeGetRows($result) {//use to retrieve rows of data
254  try {
255  if ($result->execute()) return $result->fetchAll(PDO::FETCH_ASSOC);
256  else return 0;
257  }
258  catch (PDOException $e){ $this->reportDBError($e->getMessage()."<hr>".$e->getTraceAsString()); }
259  }
260 
261  public function __clone()
262  { //not allowed
263  }
264  public function __destruct()
265  {
266  $this->dbconn = null;
267  }
268 }