XPressME Integration Kit

Trac

source: trunk/extras/wp_plugin/xpressme-backup/xpressme-backup.php @ 610

Last change on this file since 610 was 610, checked in by toemon, 15 years ago

データベースをEUC-JPからUTF-8へ変換するプラグイン追加 Fixes#347

File size: 59.1 KB
Line 
1<?php
2/*
3Plugin Name: XPressME Database Backup
4Plugin URI: http://ja.xpressme.info/
5Description: On-demand backup of your WordPress database.  Navigate to <a href="edit.php?page=xpressme-backup">Tools &rarr; Backup</a> to get started.
6Author: toemon
7Author URI: http://ja.xpressme.info
8Version: 1.0
9
10Originally modified from Austin Matzko's WordPress Database Backup(http://www.ilfilosofo.com/blog/wp-db-backup) plugin.
11
12Copyright 2008  toemon
13
14    This program is free software; you can redistribute it and/or modify
15    it under the terms of the GNU General Public License as published by
16    the Free Software Foundation; either version 2 of the License, or
17    (at your option) any later version.
18
19    This program is distributed in the hope that it will be useful,
20    but WITHOUT ANY WARRANTY; without even the implied warranty of
21    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22    GNU General Public License for more details.
23
24    You should have received a copy of the GNU General Public License
25    along with this program; if not, write to the Free Software
26    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
27*/
28
29/**
30 * Change WP_BACKUP_DIR if you want to
31 * use a different backup location
32 */
33
34$rand = substr( md5( md5( DB_PASSWORD ) ), -5 );
35global $wpdbb_content_dir, $wpdbb_content_url, $wpdbb_plugin_dir;
36$wpdbb_content_dir = ( defined('WP_CONTENT_DIR') ) ? WP_CONTENT_DIR : ABSPATH . 'wp-content';
37$wpdbb_content_url = ( defined('WP_CONTENT_URL') ) ? WP_CONTENT_URL : get_option('siteurl') . '/wp-content';
38$wpdbb_plugin_dir = ( defined('WP_PLUGIN_DIR') ) ? WP_PLUGIN_DIR : $wpdbb_content_dir . '/plugins';
39
40if ( ! defined('WP_BACKUP_DIR') ) {
41        define('WP_BACKUP_DIR', $wpdbb_content_dir . '/backup-' . $rand . '/');
42}
43
44if ( ! defined('WP_BACKUP_URL') ) {
45        define('WP_BACKUP_URL', $wpdbb_content_url . '/backup-' . $rand . '/');
46}
47
48if ( ! defined('ROWS_PER_SEGMENT') ) {
49        define('ROWS_PER_SEGMENT', 100);
50}
51
52/**
53 * Set MOD_EVASIVE_OVERRIDE to true
54 * and increase MOD_EVASIVE_DELAY
55 * if the backup stops prematurely.
56 */
57// define('MOD_EVASIVE_OVERRIDE', false);
58if ( ! defined('MOD_EVASIVE_DELAY') ) {
59        define('MOD_EVASIVE_DELAY', '500');
60}
61load_plugin_textdomain('xpressme-backup', 'wp-content/plugins/xpressme-backup');
62
63class wpdbBackup {
64
65        var $backup_complete = false;
66        var $backup_file = '';
67        var $backup_filename;
68        var $core_table_names = array();
69        var $errors = array();
70        var $basename;
71        var $page_url;
72        var $referer_check_key;
73        var $version = '2.1.5-alpha';
74
75        function gzip() {
76                return function_exists('gzopen');
77        }
78
79        function module_check() {
80                $mod_evasive = false;
81                if ( true === MOD_EVASIVE_OVERRIDE ) return true;
82                if ( false === MOD_EVASIVE_OVERRIDE ) return false;
83                if ( function_exists('apache_get_modules') )
84                        foreach( (array) apache_get_modules() as $mod )
85                                if ( false !== strpos($mod,'mod_evasive') || false !== strpos($mod,'mod_dosevasive') )
86                                        return true;
87                return false;
88        }
89
90        function wpdbBackup() {
91                global $table_prefix, $wpdb;
92                add_action('wp_ajax_save_backup_time', array(&$this, 'save_backup_time'));
93                add_action('init', array(&$this, 'init_textdomain'));
94                add_action('load-update-core.php', array(&$this, 'update_notice_action'));
95                add_action('wp_db_backup_cron', array(&$this, 'cron_backup'));
96                add_action('xpressme_cron_daily', array(&$this, 'xpressme_cron_daily'));
97                add_filter('cron_schedules', array(&$this, 'add_sched_options'));
98                add_filter('wp_db_b_schedule_choices', array(&$this, 'schedule_choices'));
99               
100                $table_prefix = ( isset( $table_prefix ) ) ? $table_prefix : $wpdb->prefix;
101                $datum = date("Ymd_B");
102                $this->backup_filename = DB_NAME . "_$table_prefix$datum.sql";
103                if ($this->gzip()) $this->backup_filename .= '.gz';
104
105                $possible_names = array(
106                        'categories',
107                        'comments',
108                        'link2cat',
109                        'linkcategories',
110                        'links',
111                        'options',
112                        'post2cat',
113                        'postmeta',
114                        'posts',
115                        'terms',
116                        'term_taxonomy',
117                        'term_relationships',
118                        'users',
119                );
120                $xpress_possible_names = array(
121                        'usermeta',
122                        'd3forum_link',
123                        'group_role',
124                        'views',
125                        'notify_reserve',
126                );
127
128                foreach( $possible_names as $name ) {
129                        if ( isset( $wpdb->{$name} ) ) {
130                                $this->core_table_names[] = $wpdb->{$name};
131                        }
132                }
133                foreach( $xpress_possible_names as $name ) {
134                                $this->core_table_names[] = $table_prefix . $name;
135                }
136       
137                $this->backup_dir = trailingslashit(apply_filters('wp_db_b_backup_dir', WP_BACKUP_DIR));
138                $this->basename = 'xpressme-backup';
139       
140                $this->referer_check_key = $this->basename . '-download_' . DB_NAME;
141                $query_args = array( 'page' => $this->basename );
142                if ( function_exists('wp_create_nonce') )
143                        $query_args = array_merge( $query_args, array('_wpnonce' => wp_create_nonce($this->referer_check_key)) );
144                $base = ( function_exists('site_url') ) ? site_url('', 'admin') : get_option('siteurl');
145                $this->page_url = add_query_arg( $query_args, $base . '/wp-admin/edit.php');
146                if (isset($_POST['do_backup'])) {
147                        $this->wp_secure('fatal');
148                        check_admin_referer($this->referer_check_key);
149                        $this->can_user_backup('main');
150                        // save exclude prefs
151
152                        $exc_revisions = (array) $_POST['exclude-revisions'];
153                        $exc_spam = (array) $_POST['exclude-spam'];
154                        update_option('xpressme_backup_excs', array('revisions' => $exc_revisions, 'spam' => $exc_spam));
155                       
156                        $do_euc_to_utf8 = $_POST['euc_to_utf8'];
157                        $do_rename_prefix = $_POST['do_rename_prefix'];
158                        $before_prefix = $_POST['before_prefix'];
159                        $after_prefix = $_POST['after_prefix'];
160                        $do_change_uri = $_POST['do_change_uri'];
161                        $before_uri = $_POST['before_uri'];
162                        $after_uri = $_POST['after_uri'];
163
164                        update_option('xpressme_backup_extras_option',
165                                array('do_euc_to_utf8' => $do_euc_to_utf8,
166                                        'do_rename_prefix' => $do_rename_prefix,
167                                        'before_prefix' => $before_prefix,
168                                        'after_prefix' => $after_prefix,
169                                        'do_change_uri' => $do_change_uri,
170                                        'before_uri' => $before_uri,
171                                        'after_uri' => $after_uri
172                                )
173                        );
174                               
175                        switch($_POST['do_backup']) {
176                        case 'backup':
177                                add_action('init', array(&$this, 'perform_backup'));
178                                break;
179                        case 'fragments':
180                                add_action('admin_menu', array(&$this, 'fragment_menu'));
181                                break;                         
182                        }
183                } elseif (isset($_GET['fragment'] )) {
184                        $this->can_user_backup('frame');
185                        add_action('init', array(&$this, 'init'));
186                } elseif (isset($_GET['backup'] )) {
187                        $this->can_user_backup();
188                        add_action('init', array(&$this, 'init'));
189                } else {
190                        add_action('admin_menu', array(&$this, 'admin_menu'));
191                }
192        }
193       
194        function init() {
195                $this->can_user_backup();
196                if (isset($_GET['backup'])) {
197                        $via = isset($_GET['via']) ? $_GET['via'] : 'http';
198                       
199                        $this->backup_file = $_GET['backup'];
200                        $this->validate_file($this->backup_file);
201
202                        switch($via) {
203                        case 'smtp':
204                        case 'email':
205                                $success = $this->deliver_backup($this->backup_file, 'smtp', $_GET['recipient'], 'frame');
206                                $this->error_display( 'frame' );
207                                if ( $success ) {
208                                        echo '
209                                                <!-- ' . $via . ' -->
210                                                <script type="text/javascript"><!--\\
211                                        ';
212                                        echo '
213                                                alert("' . __('Backup Complete!','xpressme-backup') . '");
214                                                window.onbeforeunload = null;
215                                                </script>
216                                        ';
217                                }
218                                break;
219                        default:
220                                $this->deliver_backup($this->backup_file, $via);
221                                $this->error_display( 'frame' );
222                        }
223                        die();
224                }
225                if (isset($_GET['fragment'] )) {
226                        list($table, $segment, $filename) = explode(':', $_GET['fragment']);
227                        $this->validate_file($filename);
228                        $this->backup_fragment($table, $segment, $filename);
229                }
230
231                die();
232        }
233
234        function init_textdomain() {
235                load_plugin_textdomain('xpressme-backup', str_replace(ABSPATH, '', dirname(__FILE__)), dirname(plugin_basename(__FILE__)));
236        }
237
238        /*
239         * Add a link to back up your database when doing a core upgrade
240         */
241        function update_notice_action() {
242                if ( 'upgrade-core' == $_REQUEST['action'] ) :
243                        ob_start(array(&$this, 'update_notice'));
244                        add_action('admin_footer', create_function('', 'ob_end_flush();'));
245                endif;
246        }
247                function update_notice($text = '') {
248                        $pattern = '#(<a href\="' . __('http://codex.wordpress.org/WordPress_Backups') . '">.*?</p>)#';
249                        $replace = '$1' . "\n<p>" . sprintf(__('Click <a href="%s" target="_blank">here</a> to back up your database using the WordPress Database Backup plugin. <strong>Note:</strong> WordPress Database Backup does <em>not</em> back up your files, just your database.', 'xpressme-backup'), 'tools.php?page=xpressme-backup') . "</p>\n";
250                        $text = preg_replace($pattern, $replace, $text);
251                        return $text;
252                }
253
254        function build_backup_script() {
255                global $table_prefix, $wpdb;
256       
257                echo "<div class='wrap'>";
258                echo    '<fieldset class="options"><legend>' . __('Progress','xpressme-backup') . '</legend>
259                        <p><strong>' .
260                                __('DO NOT DO THE FOLLOWING AS IT WILL CAUSE YOUR BACKUP TO FAIL:','xpressme-backup').
261                        '</strong></p>
262                        <ol>
263                                <li>'.__('Close this browser','xpressme-backup').'</li>
264                                <li>'.__('Reload this page','xpressme-backup').'</li>
265                                <li>'.__('Click the Stop or Back buttons in your browser','xpressme-backup').'</li>
266                        </ol>
267                        <p><strong>' . __('Progress:','xpressme-backup') . '</strong></p>
268                        <div id="meterbox" style="height:11px;width:80%;padding:3px;border:1px solid #659fff;"><div id="meter" style="height:11px;background-color:#659fff;width:0%;text-align:center;font-size:6pt;">&nbsp;</div></div>
269                        <div id="progress_message"></div>
270                        <div id="errors"></div>
271                        </fieldset>
272                        <iframe id="backuploader" src="about:blank" style="visibility:hidden;border:none;height:1em;width:1px;"></iframe>
273                        <script type="text/javascript">
274                        //<![CDATA[
275                        window.onbeforeunload = function() {
276                                return "' . __('Navigating away from this page will cause your backup to fail.', 'xpressme-backup') . '";
277                        }
278                        function setMeter(pct) {
279                                var meter = document.getElementById("meter");
280                                meter.style.width = pct + "%";
281                                meter.innerHTML = Math.floor(pct) + "%";
282                        }
283                        function setProgress(str) {
284                                var progress = document.getElementById("progress_message");
285                                progress.innerHTML = str;
286                        }
287                        function addError(str) {
288                                var errors = document.getElementById("errors");
289                                errors.innerHTML = errors.innerHTML + str + "<br />";
290                        }
291
292                        function backup(table, segment) {
293                                var fram = document.getElementById("backuploader");
294                                fram.src = "' . $this->page_url . '&fragment=" + table + ":" + segment + ":' . $this->backup_filename . ':";
295                        }
296                       
297                        var curStep = 0;
298                       
299                        function nextStep() {
300                                backupStep(curStep);
301                                curStep++;
302                        }
303                       
304                        function finishBackup() {
305                                var fram = document.getElementById("backuploader");                             
306                                setMeter(100);
307                ';
308
309                $download_uri = add_query_arg('backup', $this->backup_filename, $this->page_url);
310                switch($_POST['deliver']) {
311                case 'http':
312                        echo '
313                                setProgress("' . sprintf(__("Backup complete, preparing <a href=\\\"%s\\\">backup</a> for download...",'xpressme-backup'), $download_uri) . '");
314                                window.onbeforeunload = null;
315                                fram.src = "' . $download_uri . '";
316                        ';
317                        break;
318                case 'smtp':
319                        echo '
320                                setProgress("' . sprintf(__("Backup complete, sending <a href=\\\"%s\\\">backup</a> via email...",'xpressme-backup'), $download_uri) . '");
321                                window.onbeforeunload = null;
322                                fram.src = "' . $download_uri . '&via=email&recipient=' . $_POST['backup_recipient'] . '";
323                        ';
324                        break;
325                default:
326                        echo '
327                                setProgress("' . sprintf(__("Backup complete, download <a href=\\\"%s\\\">here</a>.",'xpressme-backup'), $download_uri) . '");
328                                window.onbeforeunload = null;
329                        ';
330                }
331               
332                echo '
333                        }
334                       
335                        function backupStep(step) {
336                                switch(step) {
337                                case 0: backup("", 0); break;
338                ';
339               
340                $also_backup = array();
341                if (isset($_POST['other_tables'])) {
342                        $also_backup = $_POST['other_tables'];
343                } else {
344                        $also_backup = array();
345                }
346                $core_tables = $_POST['core_tables'];
347                $tables = array_merge($core_tables, $also_backup);
348                $step_count = 1;
349                foreach ($tables as $table) {
350                        $rec_count = $wpdb->get_var("SELECT count(*) FROM {$table}");
351                        $rec_segments = ceil($rec_count / ROWS_PER_SEGMENT);
352                        $table_count = 0;
353                        if ( $this->module_check() ) {
354                                $delay = "setTimeout('";
355                                $delay_time = "', " . (int) MOD_EVASIVE_DELAY . ")";
356                        }
357                        else { $delay = $delay_time = ''; }
358                        do {
359                                echo "case {$step_count}: {$delay}backup(\"{$table}\", {$table_count}){$delay_time}; break;\n";
360                                $step_count++;
361                                $table_count++;
362                        } while($table_count < $rec_segments);
363                        echo "case {$step_count}: {$delay}backup(\"{$table}\", -1){$delay_time}; break;\n";
364                        $step_count++;
365                }
366                echo "case {$step_count}: finishBackup(); break;";
367               
368                echo '
369                                }
370                                if(step != 0) setMeter(100 * step / ' . $step_count . ');
371                        }
372
373                        nextStep();
374                        // ]]>
375                        </script>
376        </div>
377                ';
378                $this->backup_menu();
379        }
380
381        function backup_fragment($table, $segment, $filename) {
382                global $table_prefix, $wpdb;
383                       
384                echo "$table:$segment:$filename";
385               
386                if($table == '') {
387                        $msg = __('Creating backup file...','xpressme-backup');
388                } else {
389                        if($segment == -1) {
390                                $msg = sprintf(__('Finished backing up table \\"%s\\".','xpressme-backup'), $table);
391                        } else {
392                                $msg = sprintf(__('Backing up table \\"%s\\"...','xpressme-backup'), $table);
393                        }
394                }
395               
396                if (is_writable($this->backup_dir)) {
397                        $this->fp = $this->open($this->backup_dir . $filename, 'a');
398                        if(!$this->fp) {
399                                $this->error(__('Could not open the backup file for writing!','xpressme-backup'));
400                                $this->error(array('loc' => 'frame', 'kind' => 'fatal', 'msg' =>  __('The backup file could not be saved.  Please check the permissions for writing to your backup directory and try again.','xpressme-backup')));
401                        }
402                        else {
403                                if($table == '') {             
404                                        //Begin new backup of MySql
405                                        $this->stow("# " . __('WordPress MySQL database backup','xpressme-backup') . "\n");
406                                        $this->stow("#\n");
407                                        $this->stow("# " . sprintf(__('Generated: %s','xpressme-backup'),date("l j. F Y H:i T")) . "\n");
408                                        $this->stow("# " . sprintf(__('Hostname: %s','xpressme-backup'),DB_HOST) . "\n");
409                                        $this->stow("# " . sprintf(__('Database: %s','xpressme-backup'),$this->backquote(DB_NAME)) . "\n");
410                                        $this->stow("# --------------------------------------------------------\n");
411                                } else {
412                                        if($segment == 0) {
413                                                // Increase script execution time-limit to 15 min for every table.
414                                                if ( !ini_get('safe_mode')) @set_time_limit(15*60);
415                                                // Create the SQL statements
416                                                $this->stow("# --------------------------------------------------------\n");
417                                                $this->stow("# " . sprintf(__('Table: %s','xpressme-backup'),$this->backquote($table)) . "\n");
418                                                $this->stow("# --------------------------------------------------------\n");
419                                        }                       
420                                        $this->backup_table($table, $segment);
421                                }
422                        }
423                } else {
424                        $this->error(array('kind' => 'fatal', 'loc' => 'frame', 'msg' => __('The backup directory is not writeable!  Please check the permissions for writing to your backup directory and try again.','xpressme-backup')));
425                }
426
427                if($this->fp) $this->close($this->fp);
428               
429                $this->error_display('frame');
430
431                echo '<script type="text/javascript"><!--//
432                var msg = "' . $msg . '";
433                window.parent.setProgress(msg);
434                window.parent.nextStep();
435                //--></script>
436                ';
437                die();
438        }
439
440        function perform_backup() {
441                // are we backing up any other tables?
442                $also_backup = array();
443                if (isset($_POST['other_tables']))
444                        $also_backup = $_POST['other_tables'];
445                $core_tables = $_POST['core_tables'];
446                $this->backup_file = $this->db_backup($core_tables, $also_backup);
447                if (false !== $this->backup_file) {
448                        if ('smtp' == $_POST['deliver']) {
449                                $this->deliver_backup($this->backup_file, $_POST['deliver'], $_POST['backup_recipient'], 'main');
450                                wp_redirect($this->page_url);
451                        } elseif ('http' == $_POST['deliver']) {
452                                $download_uri = add_query_arg('backup',$this->backup_file,$this->page_url);
453                                wp_redirect($download_uri);
454                                exit;
455                        }
456                        // we do this to say we're done.
457                        $this->backup_complete = true;
458                }
459        }
460
461        function admin_header() {
462                ?>
463                <script type="text/javascript">
464                //<![CDATA[
465                if ( 'undefined' != typeof addLoadEvent ) {
466                        addLoadEvent(function() {
467                                var t = {'extra-tables-list':{name: 'other_tables[]'}, 'include-tables-list':{name: 'xpressme_cron_backup_tables[]'}};
468
469                                for ( var k in t ) {
470                                        t[k].s = null;
471                                        var d = document.getElementById(k);
472                                        if ( ! d )
473                                                continue;
474                                        var ul = d.getElementsByTagName('ul').item(0);
475                                        if ( ul ) {
476                                                var lis = ul.getElementsByTagName('li');
477                                                if ( 3 > lis.length )
478                                                        return;
479                                                var text = document.createElement('p');
480                                                text.className = 'instructions';
481                                                text.innerHTML = '<?php _e('Click and hold down <code>[SHIFT]</code> to toggle multiple checkboxes', 'xpressme-backup'); ?>';
482                                                ul.parentNode.insertBefore(text, ul);
483                                        }
484                                        t[k].p = d.getElementsByTagName("input");
485                                        for(var i=0; i < t[k].p.length; i++)
486                                                if(t[k].name == t[k].p[i].getAttribute('name')) {
487                                                        t[k].p[i].id = k + '-table-' + i;
488                                                        t[k].p[i].onkeyup = t[k].p[i].onclick = function(e) {
489                                                                e = e ? e : event;
490                                                                if ( 16  == e.keyCode )
491                                                                        return;
492                                                                var match = /([\w-]*)-table-(\d*)/.exec(this.id);
493                                                                var listname = match[1];
494                                                                var that = match[2];
495                                                                if ( null === t[listname].s )
496                                                                        t[listname].s = that;
497                                                                else if ( e.shiftKey ) {
498                                                                        var start = Math.min(that, t[listname].s) + 1;
499                                                                        var end = Math.max(that, t[listname].s);
500                                                                        for( var j=start; j < end; j++)
501                                                                                t[listname].p[j].checked = t[listname].p[j].checked ? false : true;
502                                                                        t[listname].s = null;
503                                                                }
504                                                        }
505                                                }
506                                }
507
508                                <?php if ( function_exists('wp_schedule_event') ) : // needs to be at least WP 2.1 for ajax ?>
509                                if ( 'undefined' == typeof XMLHttpRequest )
510                                        var xml = new ActiveXObject( navigator.userAgent.indexOf('MSIE 5') >= 0 ? 'Microsoft.XMLHTTP' : 'Msxml2.XMLHTTP' );
511                                else
512                                        var xml = new XMLHttpRequest();
513
514                                var initTimeChange = function() {
515                                        var timeWrap = document.getElementById('backup-time-wrap');
516                                        var backupTime = document.getElementById('next-backup-time');
517                                        if ( !! timeWrap && !! backupTime ) {
518                                                var span = document.createElement('span');
519                                                span.className = 'submit';
520                                                span.id = 'change-wrap';
521                                                span.innerHTML = '<input type="submit" id="change-backup-time" name="change-backup-time" value="<?php _e('Change','xpressme-backup'); ?>" />';
522                                                timeWrap.appendChild(span);
523                                                backupTime.ondblclick = function(e) { span.parentNode.removeChild(span); clickTime(e, backupTime); };
524                                                span.onclick = function(e) { span.parentNode.removeChild(span); clickTime(e, backupTime); };
525                                        }
526                                }
527
528                                var clickTime = function(e, backupTime) {
529                                        var tText = backupTime.innerHTML;
530                                        backupTime.innerHTML = '<input type="text" value="' + tText + '" name="backup-time-text" id="backup-time-text" /> <span class="submit"><input type="submit" name="save-backup-time" id="save-backup-time" value="<?php _e('Save', 'xpressme-backup'); ?>" /></span>';
531                                        backupTime.ondblclick = null;
532                                        var mainText = document.getElementById('backup-time-text');
533                                        mainText.focus();
534                                        var saveTButton = document.getElementById('save-backup-time');
535                                        if ( !! saveTButton )
536                                                saveTButton.onclick = function(e) { saveTime(backupTime, mainText); return false; };
537                                        if ( !! mainText )
538                                                mainText.onkeydown = function(e) {
539                                                        e = e || window.event;
540                                                        if ( 13 == e.keyCode ) {
541                                                                saveTime(backupTime, mainText);
542                                                                return false;
543                                                        }
544                                                }
545                                }
546
547                                var saveTime = function(backupTime, mainText) {
548                                        var tVal = mainText.value;
549
550                                        xml.open('POST', 'admin-ajax.php', true);
551                                        xml.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
552                                        if ( xml.overrideMimeType )
553                                                xml.setRequestHeader('Connection', 'close');
554                                        xml.send('action=save_backup_time&_wpnonce=<?php echo wp_create_nonce($this->referer_check_key); ?>&backup-time='+tVal);
555                                        xml.onreadystatechange = function() {
556                                                if ( 4 == xml.readyState && '0' != xml.responseText ) {
557                                                        backupTime.innerHTML = xml.responseText;
558                                                        initTimeChange();
559                                                }
560                                        }
561                                }
562
563                                initTimeChange();
564                                <?php endif; // wp_schedule_event exists ?>
565                        });
566                }
567                //]]>
568                </script>
569                <style type="text/css">
570                        .xpressme-backup-updated {
571                                margin-top: 1em;
572                        }
573
574                        fieldset.options {
575                                border: 1px solid;
576                                margin-top: 1em;
577                                padding: 1em;
578                        }
579                                fieldset.options div.tables-list {
580                                        float: left;
581                                        padding: 1em;
582                                }
583
584                                fieldset.options input {
585                                }
586
587                                fieldset.options legend {
588                                        font-size: larger;
589                                        font-weight: bold;
590                                        margin-bottom: .5em;
591                                        padding: 1em;
592                                }
593               
594                                fieldset.options .instructions {
595                                        font-size: smaller;
596                                }
597
598                                fieldset.options ul {
599                                        list-style-type: none;
600                                }
601                                        fieldset.options li {
602                                                text-align: left;
603                                        }
604
605                                fieldset.options .submit {
606                                        border-top: none;
607                                }
608                </style>
609                <?php
610        }
611
612        function admin_load() {
613                add_action('admin_head', array(&$this, 'admin_header'));
614        }
615
616        function admin_menu() {
617                $_page_hook = add_management_page(__('XPressME Backup','xpressme-backup'), __('XPressME Backup','xpressme-backup'), 'import', $this->basename, array(&$this, 'backup_menu'));
618                add_action('load-' . $_page_hook, array(&$this, 'admin_load'));
619                if ( function_exists('add_contextual_help') ) {
620                        $text = $this->help_menu();
621                        add_contextual_help($_page_hook, $text);
622                }
623        }
624
625        function fragment_menu() {
626                $page_hook = add_management_page(__('XPressME Backup','xpressme-backup'), __('XPressME Backup','xpressme-backup'), 'import', $this->basename, array(&$this, 'build_backup_script'));
627                add_action('load-' . $page_hook, array(&$this, 'admin_load'));
628        }
629
630        /**
631         * Add WP-DB-Backup-specific help options to the 2.7 =< WP contextual help menu
632         * return string The text of the help menu.
633         */
634        function help_menu() {
635                $text = '';
636//              $text = "\n<a href=\"http://wordpress.org/extend/plugins/xpressme-backup/faq/\" target=\"_blank\">" . __('FAQ', 'xpressme-backup') . '</a>';
637//              $text .= "\n<br />\n<a href=\"http://www.ilfilosofo.com/forum/forum/2\" target=\"_blank\">" . __('WP-DB-Backup Support Forum', 'xpressme-backup') . '</a>';
638                return $text;
639        }
640
641        function save_backup_time() {
642                if ( $this->can_user_backup() ) {
643                        // try to get a time from the input string
644                        $time = strtotime(strval($_POST['backup-time']));
645                        if ( ! empty( $time ) && time() < $time ) {
646                                wp_clear_scheduled_hook( 'wp_db_backup_cron' ); // unschedule previous
647                                $scheds = (array) wp_get_schedules();
648                                $name = get_option('xpressme_cron_backup_schedule');
649                                if ( 0 != $time ) {
650                                        wp_schedule_event($time, $name, 'wp_db_backup_cron');
651                                        echo gmdate(get_option('date_format') . ' ' . get_option('time_format'), $time + (get_option('gmt_offset') * 3600));
652                                        exit;
653                                }
654                        }
655                } else {
656                        die(0);
657                }
658        }
659
660        /**
661         * Better addslashes for SQL queries.
662         * Taken from phpMyAdmin.
663         */
664        function sql_addslashes($a_string = '', $is_like = false) {
665                if ($is_like) $a_string = str_replace('\\', '\\\\\\\\', $a_string);
666                else $a_string = str_replace('\\', '\\\\', $a_string);
667                return str_replace('\'', '\\\'', $a_string);
668        }
669
670        /**
671         * Add backquotes to tables and db-names in
672         * SQL queries. Taken from phpMyAdmin.
673         */
674        function backquote($a_name) {
675                if (!empty($a_name) && $a_name != '*') {
676                        if (is_array($a_name)) {
677                                $result = array();
678                                reset($a_name);
679                                while(list($key, $val) = each($a_name))
680                                        $result[$key] = '`' . $val . '`';
681                                return $result;
682                        } else {
683                                return '`' . $a_name . '`';
684                        }
685                } else {
686                        return $a_name;
687                }
688        }
689
690        function open($filename = '', $mode = 'w') {
691                if ('' == $filename) return false;
692                if ($this->gzip())
693                        $fp = @gzopen($filename, $mode);
694                else
695                        $fp = @fopen($filename, $mode);
696                return $fp;
697        }
698
699        function close($fp) {
700                if ($this->gzip()) gzclose($fp);
701                else fclose($fp);
702        }
703
704        /**
705         * Write to the backup file
706         * @param string $query_line the line to write
707         * @return null
708         */
709        function stow($query_line) {
710                $query_line = $this->extras_filter($query_line);
711                if ($this->gzip()) {
712                        if(! @gzwrite($this->fp, $query_line))
713                                $this->error(__('There was an error writing a line to the backup script:','xpressme-backup') . '  ' . $query_line . '  ' . $php_errormsg);
714                } else {
715                        if(false === @fwrite($this->fp, $query_line))
716                                $this->error(__('There was an error writing a line to the backup script:','xpressme-backup') . '  ' . $query_line . '  ' . $php_errormsg);
717                }
718        }
719       
720        /**
721         * Logs any error messages
722         * @param array $args
723         * @return bool
724         */
725        function error($args = array()) {
726                if ( is_string( $args ) )
727                        $args = array('msg' => $args);
728                $args = array_merge( array('loc' => 'main', 'kind' => 'warn', 'msg' => ''), $args);
729                $this->errors[$args['kind']][] = $args['msg'];
730                if ( 'fatal' == $args['kind'] || 'frame' == $args['loc'])
731                        $this->error_display($args['loc']);
732                return true;
733        }
734
735        /**
736         * Displays error messages
737         * @param array $errs
738         * @param string $loc
739         * @return string
740         */
741        function error_display($loc = 'main', $echo = true) {
742                $errs = $this->errors;
743                unset( $this->errors );
744                if ( ! count($errs) ) return;
745                $msg = '';
746                $err_list = array_slice(array_merge( (array) $errs['fatal'], (array) $errs['warn']), 0, 10);
747                if ( 10 == count( $err_list ) )
748                        $err_list[9] = __('Subsequent errors have been omitted from this log.','xpressme-backup');
749                $wrap = ( 'frame' == $loc ) ? "<script type=\"text/javascript\">\n var msgList = ''; \n %1\$s \n if ( msgList ) alert(msgList); \n </script>" : '%1$s';
750                $line = ( 'frame' == $loc ) ?
751                        "try{ window.parent.addError('%1\$s'); } catch(e) { msgList += ' %1\$s';}\n" :
752                        "%1\$s<br />\n";
753                foreach( (array) $err_list as $err )
754                        $msg .= sprintf($line,str_replace(array("\n","\r"), '', addslashes($err)));
755                $msg = sprintf($wrap,$msg);
756                if ( count($errs['fatal'] ) ) {
757                        if ( function_exists('wp_die') && 'frame' != $loc ) wp_die(stripslashes($msg));
758                        else die($msg);
759                }
760                else {
761                        if ( $echo ) echo $msg;
762                        else return $msg;
763                }
764        }
765
766        /**
767         * Taken partially from phpMyAdmin and partially from
768         * Alain Wolf, Zurich - Switzerland
769         * Website: http://restkultur.ch/personal/wolf/scripts/db_backup/
770       
771         * Modified by Scott Merrill (http://www.skippy.net/)
772         * to use the WordPress $wpdb object
773         * @param string $table
774         * @param string $segment
775         * @return void
776         */
777        function backup_table($table, $segment = 'none') {
778                global $wpdb;
779
780                $table_structure = $wpdb->get_results("DESCRIBE $table");
781                if (! $table_structure) {
782                        $this->error(__('Error getting table details','xpressme-backup') . ": $table");
783                        return false;
784                }
785       
786                if(($segment == 'none') || ($segment == 0)) {
787                        // Add SQL statement to drop existing table
788                        $this->stow("\n\n");
789                        $this->stow("#\n");
790                        $this->stow("# " . sprintf(__('Delete any existing table %s','xpressme-backup'),$this->backquote($table)) . "\n");
791                        $this->stow("#\n");
792                        $this->stow("\n");
793                        $this->stow("DROP TABLE IF EXISTS " . $this->backquote($table) . ";\n");
794                       
795                        // Table structure
796                        // Comment in SQL-file
797                        $this->stow("\n\n");
798                        $this->stow("#\n");
799                        $this->stow("# " . sprintf(__('Table structure of table %s','xpressme-backup'),$this->backquote($table)) . "\n");
800                        $this->stow("#\n");
801                        $this->stow("\n");
802                       
803                        $create_table = $wpdb->get_results("SHOW CREATE TABLE $table", ARRAY_N);
804                        if (false === $create_table) {
805                                $err_msg = sprintf(__('Error with SHOW CREATE TABLE for %s.','xpressme-backup'), $table);
806                                $this->error($err_msg);
807                                $this->stow("#\n# $err_msg\n#\n");
808                        }
809                        $this->stow($create_table[0][1] . ' ;');
810                       
811                        if (false === $table_structure) {
812                                $err_msg = sprintf(__('Error getting table structure of %s','xpressme-backup'), $table);
813                                $this->error($err_msg);
814                                $this->stow("#\n# $err_msg\n#\n");
815                        }
816               
817                        // Comment in SQL-file
818                        $this->stow("\n\n");
819                        $this->stow("#\n");
820                        $this->stow('# ' . sprintf(__('Data contents of table %s','xpressme-backup'),$this->backquote($table)) . "\n");
821                        $this->stow("#\n");
822                }
823               
824                if(($segment == 'none') || ($segment >= 0)) {
825                        $defs = array();
826                        $ints = array();
827                        foreach ($table_structure as $struct) {
828                                if ( (0 === strpos($struct->Type, 'tinyint')) ||
829                                        (0 === strpos(strtolower($struct->Type), 'smallint')) ||
830                                        (0 === strpos(strtolower($struct->Type), 'mediumint')) ||
831                                        (0 === strpos(strtolower($struct->Type), 'int')) ||
832                                        (0 === strpos(strtolower($struct->Type), 'bigint')) ) {
833                                                $defs[strtolower($struct->Field)] = ( null === $struct->Default ) ? 'NULL' : $struct->Default;
834                                                $ints[strtolower($struct->Field)] = "1";
835                                }
836                        }
837                       
838                       
839                        // Batch by $row_inc
840                       
841                        if($segment == 'none') {
842                                $row_start = 0;
843                                $row_inc = ROWS_PER_SEGMENT;
844                        } else {
845                                $row_start = $segment * ROWS_PER_SEGMENT;
846                                $row_inc = ROWS_PER_SEGMENT;
847                        }
848                       
849                        do {   
850                                // don't include extra stuff, if so requested
851                                $excs = (array) get_option('xpressme_backup_excs');
852
853                                $where = '';
854                                if ( is_array($excs['spam'] ) && in_array($table, $excs['spam']) ) {
855                                        $where = ' WHERE comment_approved != "spam"';
856                                } elseif ( is_array($excs['revisions'] ) && in_array($table, $excs['revisions']) ) {
857                                        $where = ' WHERE post_type != "revision"';
858                                }
859                               
860                                if ( !ini_get('safe_mode')) @set_time_limit(15*60);
861                                $table_data = $wpdb->get_results("SELECT * FROM $table $where LIMIT {$row_start}, {$row_inc}", ARRAY_A);
862
863                                $entries = 'INSERT INTO ' . $this->backquote($table) . ' VALUES (';     
864                                //    \x08\\x09, not required
865                                $search = array("\x00", "\x0a", "\x0d", "\x1a");
866                                $replace = array('\0', '\n', '\r', '\Z');
867                                if($table_data) {
868                                        foreach ($table_data as $row) {
869                                                $values = array();
870                                                foreach ($row as $key => $value) {
871                                                        if ($ints[strtolower($key)]) {
872                                                                // make sure there are no blank spots in the insert syntax,
873                                                                // yet try to avoid quotation marks around integers
874                                                                $value = ( null === $value || '' === $value) ? $defs[strtolower($key)] : $value;
875                                                                $values[] = ( '' === $value ) ? "''" : $value;
876                                                        } else {
877                                                                $values[] = "'" . str_replace($search, $replace, $this->sql_addslashes($value)) . "'";
878                                                        }
879                                                }
880                                                $this->stow(" \n" . $entries . implode(', ', $values) . ');');
881                                        }
882                                        $row_start += $row_inc;
883                                }
884                        } while((count($table_data) > 0) and ($segment=='none'));
885                }
886               
887                if(($segment == 'none') || ($segment < 0)) {
888                        // Create footer/closing comment in SQL-file
889                        $this->stow("\n");
890                        $this->stow("#\n");
891                        $this->stow("# " . sprintf(__('End of data contents of table %s','xpressme-backup'),$this->backquote($table)) . "\n");
892                        $this->stow("# --------------------------------------------------------\n");
893                        $this->stow("\n");
894                }
895        } // end backup_table()
896       
897        function db_backup($core_tables, $other_tables) {
898                global $table_prefix, $wpdb;
899               
900                if (is_writable($this->backup_dir)) {
901                        $this->fp = $this->open($this->backup_dir . $this->backup_filename);
902                        if(!$this->fp) {
903                                $this->error(__('Could not open the backup file for writing!','xpressme-backup'));
904                                return false;
905                        }
906                } else {
907                        $this->error(__('The backup directory is not writeable!','xpressme-backup'));
908                        return false;
909                }
910               
911                //Begin new backup of MySql
912                $this->stow("# " . __('WordPress MySQL database backup','xpressme-backup') . "\n");
913                $this->stow("#\n");
914                $this->stow("# " . sprintf(__('Generated: %s','xpressme-backup'),date("l j. F Y H:i T")) . "\n");
915                $this->stow("# " . sprintf(__('Hostname: %s','xpressme-backup'),DB_HOST) . "\n");
916                $this->stow("# " . sprintf(__('Database: %s','xpressme-backup'),$this->backquote(DB_NAME)) . "\n");
917                $this->stow("# --------------------------------------------------------\n");
918               
919                        if ( (is_array($other_tables)) && (count($other_tables) > 0) )
920                        $tables = array_merge($core_tables, $other_tables);
921                else
922                        $tables = $core_tables;
923               
924                foreach ($tables as $table) {
925                        // Increase script execution time-limit to 15 min for every table.
926                        if ( !ini_get('safe_mode')) @set_time_limit(15*60);
927                        // Create the SQL statements
928                        $this->stow("# --------------------------------------------------------\n");
929                        $this->stow("# " . sprintf(__('Table: %s','xpressme-backup'),$this->backquote($table)) . "\n");
930                        $this->stow("# --------------------------------------------------------\n");
931                        $this->backup_table($table);
932                }
933                               
934                $this->close($this->fp);
935               
936                if (count($this->errors)) {
937                        return false;
938                } else {
939                        return $this->backup_filename;
940                }
941               
942        } //wp_db_backup
943
944        /**
945         * Sends the backed-up file via email
946         * @param string $to
947         * @param string $subject
948         * @param string $message
949         * @return bool
950         */
951        function send_mail( $to, $subject, $message, $diskfile) {
952                global $phpmailer;
953
954                $filename = basename($diskfile);
955
956                extract( apply_filters( 'wp_mail', compact( 'to', 'subject', 'message' ) ) );
957
958                if ( !is_object( $phpmailer ) || ( strtolower(get_class( $phpmailer )) != 'phpmailer' ) ) {
959                        if ( file_exists( ABSPATH . WPINC . '/class-phpmailer.php' ) )
960                                require_once ABSPATH . WPINC . '/class-phpmailer.php';
961                        if ( file_exists( ABSPATH . WPINC . '/class-smtp.php' ) )
962                                require_once ABSPATH . WPINC . '/class-smtp.php';
963                        if ( class_exists( 'PHPMailer') )
964                                $phpmailer = new PHPMailer();
965                }
966
967                // try to use phpmailer directly (WP 2.2+)
968                if ( is_object( $phpmailer ) && ( strtolower(get_class( $phpmailer )) == 'phpmailer' ) ) {
969                       
970                        // Get the site domain and get rid of www.
971                        $sitename = strtolower( $_SERVER['SERVER_NAME'] );
972                        if ( substr( $sitename, 0, 4 ) == 'www.' ) {
973                                $sitename = substr( $sitename, 4 );
974                        }
975                        $from_email = 'wordpress@' . $sitename;
976                        $from_name = 'WordPress';
977
978                        // Empty out the values that may be set
979                        $phpmailer->ClearAddresses();
980                        $phpmailer->ClearAllRecipients();
981                        $phpmailer->ClearAttachments();
982                        $phpmailer->ClearBCCs();
983                        $phpmailer->ClearCCs();
984                        $phpmailer->ClearCustomHeaders();
985                        $phpmailer->ClearReplyTos();
986
987                        $phpmailer->AddAddress( $to );
988                        $phpmailer->AddAttachment($diskfile, $filename);
989                        $phpmailer->Body = $message;
990                        $phpmailer->CharSet = apply_filters( 'wp_mail_charset', get_bloginfo('charset') );
991                        $phpmailer->From = apply_filters( 'wp_mail_from', $from_email );
992                        $phpmailer->FromName = apply_filters( 'wp_mail_from_name', $from_name );
993                        $phpmailer->IsMail();
994                        $phpmailer->Subject = $subject;
995
996                        do_action_ref_array( 'phpmailer_init', array( &$phpmailer ) );
997                       
998                        $result = @$phpmailer->Send();
999
1000                // old-style: build the headers directly
1001                } else {
1002                        $randomish = md5(time());
1003                        $boundary = "==WPBACKUP-$randomish";
1004                        $fp = fopen($diskfile,"rb");
1005                        $file = fread($fp,filesize($diskfile));
1006                        $this->close($fp);
1007                       
1008                        $data = chunk_split(base64_encode($file));
1009                       
1010                        $headers .= "MIME-Version: 1.0\n";
1011                        $headers = 'From: wordpress@' . preg_replace('#^www\.#', '', strtolower($_SERVER['SERVER_NAME'])) . "\n";
1012                        $headers .= "Content-Type: multipart/mixed; boundary=\"$boundary\"\n";
1013               
1014                        // Add a multipart boundary above the plain message
1015                        $message = "This is a multi-part message in MIME format.\n\n" .
1016                                "--{$boundary}\n" .
1017                                "Content-Type: text/plain; charset=\"" . get_bloginfo('charset') . "\"\n" .
1018                                "Content-Transfer-Encoding: 7bit\n\n" .
1019                                $message . "\n\n";
1020
1021                        // Add file attachment to the message
1022                        $message .= "--{$boundary}\n" .
1023                                "Content-Type: application/octet-stream;\n" .
1024                                " name=\"{$filename}\"\n" .
1025                                "Content-Disposition: attachment;\n" .
1026                                " filename=\"{$filename}\"\n" .
1027                                "Content-Transfer-Encoding: base64\n\n" .
1028                                $data . "\n\n" .
1029                                "--{$boundary}--\n";
1030                       
1031                        $result = @wp_mail($to, $subject, $message, $headers);
1032                }
1033                return $result;
1034
1035        }
1036
1037        function deliver_backup($filename = '', $delivery = 'http', $recipient = '', $location = 'main') {
1038                if ('' == $filename) { return false; }
1039               
1040                $diskfile = $this->backup_dir . $filename;
1041                if ('http' == $delivery) {
1042                        if (! file_exists($diskfile))
1043                                $this->error(array('kind' => 'fatal', 'msg' => sprintf(__('File not found:%s','xpressme-backup'), "&nbsp;<strong>$filename</strong><br />") . '<br /><a href="' . $this->page_url . '">' . __('Return to Backup','xpressme-backup') . '</a>'));
1044                        header('Content-Description: File Transfer');
1045                        header('Content-Type: application/octet-stream');
1046                        header('Content-Length: ' . filesize($diskfile));
1047                        header("Content-Disposition: attachment; filename=$filename");
1048                        $success = readfile($diskfile);
1049                        unlink($diskfile);
1050                } elseif ('smtp' == $delivery) {
1051                        if (! file_exists($diskfile)) {
1052                                $msg = sprintf(__('File %s does not exist!','xpressme-backup'), $diskfile);
1053                                $this->error($msg);
1054                                return false;
1055                        }
1056                        if (! is_email($recipient)) {
1057                                $recipient = get_option('admin_email');
1058                        }
1059                        $message = sprintf(__("Attached to this email is\n   %1s\n   Size:%2s kilobytes\n",'xpressme-backup'), $filename, round(filesize($diskfile)/1024));
1060                        $success = $this->send_mail($recipient, get_bloginfo('name') . ' ' . __('Database Backup','xpressme-backup'), $message, $diskfile);
1061
1062                        if ( false === $success ) {
1063                                $msg = __('The following errors were reported:','xpressme-backup') . "\n ";
1064                                if ( function_exists('error_get_last') ) {
1065                                        $err = error_get_last();
1066                                        $msg .= $err['message'];
1067                                } else {
1068                                        $msg .= __('ERROR: The mail application has failed to deliver the backup.','xpressme-backup');
1069                                }
1070                                $this->error(array('kind' => 'fatal', 'loc' => $location, 'msg' => $msg));
1071                        } else {
1072                                unlink($diskfile);
1073                        }
1074                }
1075                return $success;
1076        }
1077       
1078        function backup_menu() {
1079                global $table_prefix, $wpdb;
1080                $feedback = '';
1081                $whoops = false;
1082               
1083                // did we just do a backup?  If so, let's report the status
1084                if ( $this->backup_complete ) {
1085                        $feedback = '<div class="updated xpressme-backup-updated"><p>' . __('Backup Successful','xpressme-backup') . '!';
1086                        $file = $this->backup_file;
1087                        switch($_POST['deliver']) {
1088                        case 'http':
1089                                $feedback .= '<br />' . sprintf(__('Your backup file: <a href="%1s">%2s</a> should begin downloading shortly.','xpressme-backup'), WP_BACKUP_URL . "{$this->backup_file}", $this->backup_file);
1090                                break;
1091                        case 'smtp':
1092                                if (! is_email($_POST['backup_recipient'])) {
1093                                        $feedback .= get_option('admin_email');
1094                                } else {
1095                                        $feedback .= $_POST['backup_recipient'];
1096                                }
1097                                $feedback = '<br />' . sprintf(__('Your backup has been emailed to %s','xpressme-backup'), $feedback);
1098                                break;
1099                        case 'none':
1100                                $feedback .= '<br />' . __('Your backup file has been saved on the server. If you would like to download it now, right click and select "Save As"','xpressme-backup');
1101                                $feedback .= ':<br /> <a href="' . WP_BACKUP_URL . "$file\">$file</a> : " . sprintf(__('%s bytes','xpressme-backup'), filesize($this->backup_dir . $file));
1102                        }
1103                        $feedback .= '</p></div>';
1104                }
1105       
1106                // security check
1107                $this->wp_secure(); 
1108
1109                if (count($this->errors)) {
1110                        $feedback .= '<div class="updated xpressme-backup-updated error"><p><strong>' . __('The following errors were reported:','xpressme-backup') . '</strong></p>';
1111                        $feedback .= '<p>' . $this->error_display( 'main', false ) . '</p>';
1112                        $feedback .= "</p></div>";
1113                }
1114
1115                // did we just save options for wp-cron?
1116                if ( (function_exists('wp_schedule_event') || function_exists('xpressme_cron_init'))
1117                        && isset($_POST['xpressme_cron_backup_options']) ) :
1118                        do_action('wp_db_b_update_cron_options');
1119                        if ( function_exists('wp_schedule_event') ) {
1120                                wp_clear_scheduled_hook( 'wp_db_backup_cron' ); // unschedule previous
1121                                $scheds = (array) wp_get_schedules();
1122                                $name = strval($_POST['xpressme_cron_schedule']);
1123                                $interval = ( isset($scheds[$name]['interval']) ) ?
1124                                        (int) $scheds[$name]['interval'] : 0;
1125                                update_option('xpressme_cron_backup_schedule', $name, false);
1126                                if ( 0 !== $interval ) {
1127                                        wp_schedule_event(time() + $interval, $name, 'wp_db_backup_cron');
1128                                }
1129                        }
1130                        else {
1131                                update_option('xpressme_cron_backup_schedule', intval($_POST['cron_schedule']), false);
1132                        }
1133                        update_option('xpressme_cron_backup_tables', $_POST['xpressme_cron_backup_tables']);
1134                        if (is_email($_POST['cron_backup_recipient'])) {
1135                                update_option('xpressme_cron_backup_recipient', $_POST['cron_backup_recipient'], false);
1136                        }
1137                        $feedback .= '<div class="updated xpressme-backup-updated"><p>' . __('Scheduled Backup Options Saved!','xpressme-backup') . '</p></div>';
1138                endif;
1139               
1140                $other_tables = array();
1141                $also_backup = array();
1142       
1143                // Get complete db table list   
1144                $all_tables = $wpdb->get_results("SHOW TABLES", ARRAY_N);
1145                $all_tables = array_map(create_function('$a', 'return $a[0];'), $all_tables);
1146                // Get list of WP tables that actually exist in this DB (for 1.6 compat!)
1147                $wp_backup_default_tables = array_intersect($all_tables, $this->core_table_names);
1148                // Get list of non-WP tables
1149                $other_tables = array_diff($all_tables, $wp_backup_default_tables);
1150               
1151                if ('' != $feedback)
1152                        echo $feedback;
1153
1154                if ( ! $this->wp_secure() )     
1155                        return;
1156
1157                // Give the new dirs the same perms as wp-content.
1158//              $stat = stat( ABSPATH . 'wp-content' );
1159//              $dir_perms = $stat['mode'] & 0000777; // Get the permission bits.
1160                $dir_perms = '0777';
1161
1162                // the file doesn't exist and can't create it
1163                if ( ! file_exists($this->backup_dir) && ! @mkdir($this->backup_dir) ) {
1164                        ?><div class="updated xpressme-backup-updated error"><p><?php _e('WARNING: Your backup directory does <strong>NOT</strong> exist, and we cannot create it.','xpressme-backup'); ?></p>
1165                        <p><?php printf(__('Using your FTP client, try to create the backup directory yourself: %s', 'xpressme-backup'), '<code>' . $this->backup_dir . '</code>'); ?></p></div><?php
1166                        $whoops = true;
1167                // not writable due to write permissions
1168                } elseif ( !is_writable($this->backup_dir) && ! @chmod($this->backup_dir, $dir_perms) ) {
1169                        ?><div class="updated xpressme-backup-updated error"><p><?php _e('WARNING: Your backup directory is <strong>NOT</strong> writable! We cannot create the backup files.','xpressme-backup'); ?></p>
1170                        <p><?php printf(__('Using your FTP client, try to set the backup directory&rsquo;s write permission to %1$s or %2$s: %3$s', 'xpressme-backup'), '<code>777</code>', '<code>a+w</code>', '<code>' . $this->backup_dir . '</code>'); ?>
1171                        </p></div><?php
1172                        $whoops = true;
1173                } else {
1174                        $this->fp = $this->open($this->backup_dir . 'test' );
1175                        if( $this->fp ) {
1176                                $this->close($this->fp);
1177                                @unlink($this->backup_dir . 'test' );
1178                        // the directory is not writable probably due to safe mode
1179                        } else {
1180                                ?><div class="updated xpressme-backup-updated error"><p><?php _e('WARNING: Your backup directory is <strong>NOT</strong> writable! We cannot create the backup files.','xpressme-backup'); ?></p><?php
1181                                if( ini_get('safe_mode') ){
1182                                        ?><p><?php _e('This problem seems to be caused by your server&rsquo;s <code>safe_mode</code> file ownership restrictions, which limit what files web applications like WordPress can create.', 'xpressme-backup'); ?></p><?php
1183                                }
1184                                ?><?php printf(__('You can try to correct this problem by using your FTP client to delete and then re-create the backup directory: %s', 'xpressme-backup'), '<code>' . $this->backup_dir . '</code>');
1185                                ?></div><?php
1186                                $whoops = true;
1187                        }
1188                }
1189
1190               
1191
1192                if ( !file_exists($this->backup_dir . 'index.php') )
1193                        @ touch($this->backup_dir . 'index.php');
1194                ?><div class='wrap'>
1195                <h2><?php _e('Backup','xpressme-backup') ?></h2>
1196                <form method="post" action="">
1197                <?php if ( function_exists('wp_nonce_field') ) wp_nonce_field($this->referer_check_key); ?>
1198                <fieldset class="options"><legend><?php _e('Tables','xpressme-backup') ?></legend>
1199                <table align="center" cellspacing="5" cellpadding="5">
1200                <tr><td width="50%" align="left" class="alternate" valign="top">
1201                <div class="tables-list core-tables alternate">
1202                <h4><?php _e('These core WordPress tables will always be backed up:','xpressme-backup') ?></h4><ul><?php
1203                $excs = (array) get_option('xpressme_backup_excs');
1204
1205                foreach ($wp_backup_default_tables as $table) {
1206                        if ( $table == $wpdb->comments ) {
1207                                $checked = ( isset($excs['spam']) && is_array($excs['spam'] ) && in_array($table, $excs['spam']) ) ? ' checked=\'checked\'' : '';
1208                                echo "<li><input type='hidden' name='core_tables[]' value='$table' /><code>$table</code> <span class='instructions'> <input type='checkbox' name='exclude-spam[]' value='$table' $checked /> " . __('Exclude spam comments', 'xpressme-backup') . '</span></li>';
1209                        } elseif ( function_exists('wp_get_post_revisions') && $table == $wpdb->posts ) {
1210                                        $checked = ( isset($excs['revisions']) && is_array($excs['revisions'] ) && in_array($table, $excs['revisions']) ) ? ' checked=\'checked\'' : '';
1211                                echo "<li><input type='hidden' name='core_tables[]' value='$table' /><code>$table</code> <span class='instructions'> <input type='checkbox' name='exclude-revisions[]' value='$table' $checked /> " . __('Exclude post revisions', 'xpressme-backup') . '</span></li>';
1212                        } else {
1213                                echo "<li><input type='hidden' name='core_tables[]' value='$table' /><code>$table</code></li>";
1214                        }
1215                }
1216                ?></ul>
1217                </div>
1218                </td><td width="50%" align="left" valign="top">
1219                <div class="tables-list extra-tables" id="extra-tables-list">
1220                <?php
1221                if (count($other_tables) > 0) {
1222                        $select_all = __('Select all','xpressme-backup');
1223                        $select_none = __('Select none','xpressme-backup');
1224                        ?>
1225                        <h4><?php _e('You may choose to include any of the following tables:','xpressme-backup'); ?></h4>
1226                        <ul>
1227                        <script type="text/javascript">
1228                        //<![CDATA[
1229                                var wpdbBackup = function() {};
1230                                (function(b){
1231                                        var n = function(c) {
1232                                                var p = document.getElementsByTagName("input");
1233                                                for(var i=0;i<p.length;i++)
1234                                                        if('other_tables[]' == p[i].getAttribute('name'))
1235                                                                p[i].checked = c;
1236                                        }
1237                                        b.a = function() { n(true) }
1238                                        b.n = function() { n(false) }
1239
1240                                        document.write('<p><a href="javascript:void(0)" onclick="wpdbBackup.a()"><?php echo $select_all ?></a> / <a href="javascript:void(0)" onclick="wpdbBackup.n()"><?php echo $select_none ?></a></p>');
1241                                })(wpdbBackup)
1242                        //]]>
1243                        </script>
1244       
1245                        <?php
1246                        foreach ($other_tables as $table) {
1247                                ?>
1248                                <li><label><input type="checkbox" name="other_tables[]" value="<?php echo $table; ?>" /> <code><?php echo $table; ?></code></label>
1249                                <?php
1250                        }
1251                        ?></ul><?php
1252                }
1253                ?></div>
1254                </td></tr></table>
1255                </fieldset>
1256               
1257                <fieldset class="options">
1258                        <legend><?php _e('Backup Options','xpressme-backup'); ?></legend>
1259                        <p><?php  _e('What to do with the backup file:','xpressme-backup'); ?></p>
1260                        <ul>
1261                        <li><label for="do_save">
1262                                <input type="radio" id="do_save" name="deliver" value="none" style="border:none;" />
1263                                <?php _e('Save to server','xpressme-backup');
1264                                echo " (<code>" . $this->backup_dir . "</code>)"; ?>
1265                        </label></li>
1266                        <li><label for="do_download">
1267                                <input type="radio" checked="checked" id="do_download" name="deliver" value="http" style="border:none;" />
1268                                <?php _e('Download to your computer','xpressme-backup'); ?>
1269                        </label></li>
1270                        <li><label for="do_email">
1271                                <input type="radio" name="deliver" id="do_email" value="smtp" style="border:none;" />
1272                                <?php _e('Email backup to:','xpressme-backup'); ?>
1273                                <input type="text" name="backup_recipient" size="20" value="<?php echo get_option('admin_email'); ?>" />
1274                        </label></li>
1275                        </ul>
1276                        <p><?php  _e('Backup Ditaile Options','xpressme-backup'); ?></p>
1277                        <ul>
1278                        <?php
1279                        if(WPLANG == 'ja_EUC'){
1280                                echo '<li><label for="do_euc_to_utf8">';
1281                                if($this->is_mbstring()){
1282                                        echo    '<input type="checkbox" name="euc_to_utf8" id="euc_to_utf8" value="1" />';
1283                                        echo __('Converte EUC-JP to UTF-8','xpressme-backup');
1284                                } else {
1285                                        echo    '<input type="checkbox" name="euc_to_utf8" id="euc_to_utf8" value="1" disabled="1"/>';
1286                                        echo __('Converte EUC-JP to UTF-8','xpressme-backup');
1287                                        echo ' (<span style="color:#ff0000">' . __('The server used does not support the mb_convert_encoding() function.','xpressme-backup') . '</span>)';
1288                                }
1289                                echo '</label></li>';
1290                        } else {
1291                                echo '<input type="hidden" name="euc_to_utf8" id="euc_to_utf8" value="0" />';
1292                        }
1293                        ?>
1294                        <li><label for="rename_prefix">
1295                                <input type="checkbox" name="do_rename_prefix" id="do_rename_prefix" value="1" />
1296                                <?php _e('Rename DB Prefix','xpressme-backup'); ?>
1297                                <input type="text" name="before_prefix" size="20" value="<?php echo $table_prefix; ?>" />
1298                                <?php _e('to','xpressme-backup'); ?>
1299                                <input type="text" name="after_prefix" size="20" value="<?php echo $table_prefix; ?>" />
1300                        </label></li>
1301                        <li><label for="change_uri">
1302                                <input type="checkbox" name="do_change_uri" id="do_change_uri" value="1" />
1303                                <?php $site_uri = get_option('siteurl');?>
1304                                <?php _e('Change URL','xpressme-backup'); ?>
1305                                <div style="padding-left: 20px;">
1306                                <input type="text" name="before_uri" size="50" value="<?php echo $site_uri; ?>" /><br />
1307                                <?php _e('to','xpressme-backup'); ?><br />
1308                                <input type="text" name="after_uri" size="50" value="<?php echo $site_uri; ?>" />
1309                                </div>
1310                        </label></li>
1311                        </ul>
1312                        <?php if ( ! $whoops ) : ?>
1313                        <input type="hidden" name="do_backup" id="do_backup" value="backup" />
1314                        <p class="submit">
1315                                <input type="submit" name="submit" onclick="document.getElementById('do_backup').value='fragments';" value="<?php _e('Backup now!','xpressme-backup'); ?>" />
1316                        </p>
1317                        <?php else : ?>
1318                                <div class="updated xpressme-backup-updated error"><p><?php _e('WARNING: Your backup directory is <strong>NOT</strong> writable!','xpressme-backup'); ?></p></div>
1319                        <?php endif; // ! whoops ?>
1320                </fieldset>
1321                <?php do_action('wp_db_b_backup_opts'); ?>
1322                </form>
1323               
1324                <?php
1325                // this stuff only displays if some sort of wp-cron is available
1326                $cron = ( function_exists('wp_schedule_event') ) ? true : false; // wp-cron in WP 2.1+
1327                $cron_old = ( function_exists('xpressme_cron_init') && ! $cron ) ? true : false; // wp-cron plugin by Skippy
1328                if ( $cron_old || $cron ) :
1329                        echo '<fieldset class="options"><legend>' . __('Scheduled Backup','xpressme-backup') . '</legend>';
1330                        $datetime = get_option('date_format') . ' ' . get_option('time_format');
1331                        if ( $cron ) :
1332                                $next_cron = wp_next_scheduled('wp_db_backup_cron');
1333                                if ( ! empty( $next_cron ) ) :
1334                                        ?>
1335                                        <p id="backup-time-wrap">
1336                                        <?php printf(__('Next Backup: %s','xpressme-backup'), '<span id="next-backup-time">' . gmdate($datetime, $next_cron + (get_option('gmt_offset') * 3600)) . '</span>'); ?>
1337                                        </p>
1338                                        <?php
1339                                endif;
1340                        elseif ( $cron_old ) :
1341                                ?><p><?php printf(__('Last WP-Cron Daily Execution: %s','xpressme-backup'), gmdate($datetime, get_option('xpressme_cron_daily_lastrun') + (get_option('gmt_offset') * 3600))); ?><br /><?php
1342                                printf(__('Next WP-Cron Daily Execution: %s','xpressme-backup'), gmdate($datetime, (get_option('xpressme_cron_daily_lastrun') + (get_option('gmt_offset') * 3600) + 86400))); ?></p><?php
1343                        endif;
1344                        ?><form method="post" action="">
1345                        <?php if ( function_exists('wp_nonce_field') ) wp_nonce_field($this->referer_check_key); ?>
1346                        <div class="tables-list">
1347                        <h4><?php _e('Schedule: ','xpressme-backup'); ?></h4>
1348                        <?php
1349                        if ( $cron_old ) :
1350                                $xpressme_cron_backup_schedule = get_option('xpressme_cron_backup_schedule');
1351                                $schedule = array(0 => __('None','xpressme-backup'), 1 => __('Daily','xpressme-backup'));
1352                                foreach ($schedule as $value => $name) {
1353                                        echo ' <input type="radio" style="border:none;" name="cron_schedule"';
1354                                        if ($xpressme_cron_backup_schedule == $value) {
1355                                                echo ' checked="checked" ';
1356                                        }
1357                                        echo 'value="' . $value . '" /> ' . $name;
1358                                }
1359                        elseif ( $cron ) :
1360                                echo apply_filters('wp_db_b_schedule_choices', wp_get_schedules() );
1361                        endif;
1362                        $cron_recipient = get_option('xpressme_cron_backup_recipient');
1363                        if (! is_email($cron_recipient)) {
1364                                $cron_recipient = get_option('admin_email');
1365                        }
1366                        $cron_recipient_input = '<p><label for="cron_backup_recipient">' . __('Email backup to:','xpressme-backup') . ' <input type="text" name="cron_backup_recipient" id="cron_backup_recipient" size="20" value="' . $cron_recipient . '" /></label></p>';
1367                        echo apply_filters('wp_db_b_cron_recipient_input', $cron_recipient_input);
1368                        echo '<p class="submit"><input type="submit" name="submit" value="' . __('Schedule backup','xpressme-backup') . '" /></p>';
1369                        echo '</div>';
1370                        $cron_tables = get_option('xpressme_cron_backup_tables');
1371                        if (! is_array($cron_tables)) {
1372                                $cron_tables = array();
1373                        }
1374                        if (count($other_tables) > 0) {
1375                                echo '<div class="tables-list alternate" id="include-tables-list">';
1376                                echo '<h4>' . __('Tables to include in the scheduled backup:','xpressme-backup') . '</h4><ul>';
1377                                foreach ($other_tables as $table) {
1378                                        echo '<li><input type="checkbox" ';
1379                                        if (in_array($table, $cron_tables)) {
1380                                                echo 'checked="checked" ';
1381                                        }
1382                                        echo "name='xpressme_cron_backup_tables[]' value='{$table}' /> <code>{$table}</code></li>";
1383                                }
1384                                echo '</ul></div>';
1385                        }
1386                        echo '<input type="hidden" name="xpressme_cron_backup_options" value="SET" /></form>';
1387                        echo '</fieldset>';
1388                endif; // end of wp_cron (legacy) section
1389               
1390                echo '</div><!-- .wrap -->';
1391               
1392        } // end wp_backup_menu()
1393
1394        function get_sched() {
1395                $options = array_keys( (array) wp_get_schedules() );
1396                $freq = get_option('xpressme_cron_backup_schedule');
1397                $freq = ( in_array( $freq , $options ) ) ? $freq : 'never';
1398                return $freq;
1399        }
1400
1401        function schedule_choices($schedule) { // create the cron menu based on the schedule
1402                $xpressme_cron_backup_schedule = $this->get_sched();
1403                $next_cron = wp_next_scheduled('wp_db_backup_cron');
1404                $xpressme_cron_backup_schedule = ( empty( $next_cron ) ) ? 'never' : $xpressme_cron_backup_schedule;
1405                $sort = array();
1406                foreach ( (array) $schedule as $key => $value ) $sort[$key] = $value['interval'];
1407                asort( $sort );
1408                $schedule_sorted = array();
1409                foreach ( (array) $sort as $key => $value ) $schedule_sorted[$key] = $schedule[$key];
1410                $menu = '<ul>';
1411                $schedule = array_merge( array( 'never' => array( 'interval' => 0, 'display' => __('Never','xpressme-backup') ) ),
1412                        (array) $schedule_sorted );
1413                foreach ( $schedule as $name => $settings) {
1414                        $interval = (int) $settings['interval'];
1415                        if ( 0 == $interval && ! 'never' == $name ) continue;
1416                        $display = ( ! '' == $settings['display'] ) ? $settings['display'] : sprintf(__('%s seconds','xpressme-backup'),$interval);
1417                        $menu .= "<li><input type='radio' name='xpressme_cron_schedule' style='border:none;' ";
1418                        if ($xpressme_cron_backup_schedule == $name) {
1419                                $menu .= " checked='checked' ";
1420                        }
1421                        $menu .= "value='$name' /> $display</li>";
1422                }
1423                $menu .= '</ul>';
1424                return $menu;
1425        } // end schedule_choices()
1426       
1427        function wp_cron_daily() { // for legacy cron plugin
1428                $schedule = intval(get_option('xpressme_cron_backup_schedule'));
1429                // If scheduled backup is disabled
1430                if (0 == $schedule)
1431                        return;
1432                else return $this->cron_backup();
1433        }
1434
1435        function cron_backup() {
1436                global $table_prefix, $wpdb;
1437                $all_tables = $wpdb->get_results("SHOW TABLES", ARRAY_N);
1438                $all_tables = array_map(create_function('$a', 'return $a[0];'), $all_tables);
1439                $core_tables = array_intersect($all_tables, $this->core_table_names);
1440                $other_tables = get_option('xpressme_cron_backup_tables');
1441                $recipient = get_option('xpressme_cron_backup_recipient');
1442                $backup_file = $this->db_backup($core_tables, $other_tables);
1443                if (false !== $backup_file)
1444                        return $this->deliver_backup($backup_file, 'smtp', $recipient, 'main');
1445                else return false;
1446        }
1447
1448        function add_sched_options($sched) {
1449                $sched['weekly'] = array('interval' => 604800, 'display' => __('Once Weekly','xpressme-backup'));
1450                return $sched;
1451        }
1452
1453        /**
1454         * Checks that WordPress has sufficient security measures
1455         * @param string $kind
1456         * @return bool
1457         */
1458        function wp_secure($kind = 'warn', $loc = 'main') {
1459                global $wp_version;
1460               
1461                if ( function_exists('wp_verify_nonce') ) return true;
1462                else {
1463                        $this->error(array('kind' => $kind, 'loc' => $loc, 'msg' => sprintf(__('Your WordPress version, %1s, lacks important security features without which it is unsafe to use the WP-DB-Backup plugin.  Hence, this plugin is automatically disabled.  Please consider <a href="%2s">upgrading WordPress</a> to a more recent version.','xpressme-backup'),$wp_version,'http://wordpress.org/download/')));
1464                        return false;
1465                }
1466               
1467        }
1468
1469        /**
1470         * Checks that the user has sufficient permission to backup
1471         * @param string $loc
1472         * @return bool
1473         */
1474        function can_user_backup($loc = 'main') {
1475                $can = false;
1476                // make sure WPMU users are site admins, not ordinary admins
1477                if ( function_exists('is_site_admin') && ! is_site_admin() )
1478                        return false;
1479                if ( ( $this->wp_secure('fatal', $loc) ) && current_user_can('import') )
1480                        $can = $this->verify_nonce($_REQUEST['_wpnonce'], $this->referer_check_key, $loc);
1481                if ( false == $can )
1482                        $this->error(array('loc' => $loc, 'kind' => 'fatal', 'msg' => __('You are not allowed to perform backups.','xpressme-backup')));
1483                return $can;
1484        }
1485
1486        /**
1487         * Verify that the nonce is legitimate
1488         * @param string $rec   the nonce received
1489         * @param string $nonce what the nonce should be
1490         * @param string $loc   the location of the check
1491         * @return bool
1492         */
1493        function verify_nonce($rec = '', $nonce = 'X', $loc = 'main') {
1494                if ( wp_verify_nonce($rec, $nonce) )
1495                        return true;
1496                else
1497                        $this->error(array('loc' => $loc, 'kind' => 'fatal', 'msg' => sprintf(__('There appears to be an unauthorized attempt from this site to access your database located at %1s.  The attempt has been halted.','xpressme-backup'),get_option('home'))));
1498        }
1499
1500        /**
1501         * Check whether a file to be downloaded is 
1502         * surreptitiously trying to download a non-backup file
1503         * @param string $file
1504         * @return null
1505         */
1506        function validate_file($file) {
1507                if ( (false !== strpos($file, '..')) || (false !== strpos($file, './')) || (':' == substr($file, 1, 1)) )
1508                        $this->error(array('kind' => 'fatal', 'loc' => 'frame', 'msg' => __("Cheatin' uh ?",'xpressme-backup')));
1509        }
1510       
1511        function extras_filter($query_line){
1512                $extras_option = get_option('xpressme_backup_extras_option');
1513                if ($extras_option['do_euc_to_utf8'] && $this->is_mbstring()){
1514                        $query_line = mb_convert_encoding(mb_convert_encoding($query_line,"sjis-win","EUC-JP"),"UTF-8","sjis-win");
1515                        $tmp = preg_replace('/DEFAULT\s*CHARSET\s*=\s*ujis/','DEFAULT CHARSET=utf8',$query_line);
1516                        if (empty($buf)) $query_line = $tmp;
1517                        if (preg_match_all('/s:([0-9]+):"(.*?)";/',$query_line,$matchs)){
1518                                $i_count = count($matchs[0]);
1519                                for($i=0; $i < $i_count ;$i++){
1520                                        $org = $matchs[0][$i];
1521                                        $num = $matchs[1][$i];
1522                                        $str = $matchs[2][$i];
1523                                        $str =  str_replace('\r\n','\n',$str);
1524
1525                                        $volm = strlen(bin2hex($str)) / 2;
1526                                       
1527                                        if ($num != $volm){
1528                                                $org =  str_replace('\\','\\\\',$org);
1529                                                $org =  str_replace('/','\\/',$org);
1530                                                $org =  str_replace('(','\\(',$org);
1531                                                $org =  str_replace(')','\\)',$org);
1532                                                $org =  str_replace('?','\\?',$org);
1533                                                $org =  str_replace('+','\\+',$org);
1534                                                $org =  str_replace('*','\\*',$org);
1535                                                $org =  str_replace('[','\\[',$org);
1536                                                $org =  str_replace(']','\\]',$org);                                   
1537                                                $org =  str_replace('$','\\$',$org);
1538                                                $org =  str_replace('{','\\{',$org);                                   
1539                                                $org =  str_replace('}','\\}',$org);
1540                                                $org =  str_replace('^','\\^',$org);
1541                                                $org =  str_replace('.','\\.',$org);
1542                               
1543                                                $src = '/' . $org . '/';
1544//                                              $dist = '*************************************s:' . $num . '->' . $volm . '"' . $str . '"';
1545                                                $dist = 's:'. $volm . '"' . $str . '"';
1546                                                if(preg_match($src,$query_line)){
1547                                                        $query_line = preg_replace($src,$dist,$query_line);
1548                                                }
1549                                        }
1550                                }
1551                        }
1552                }
1553                if ($extras_option['do_rename_prefix']){
1554                        if (!empty($extras_option['before_prefix']) && !empty($extras_option['after_prefix'])){
1555                                $src = '/' . $extras_option['before_prefix'] . '/';
1556                                $dist = $extras_option['after_prefix'];
1557                                if(preg_match($src,$query_line)){
1558                                        $query_line = preg_replace($src,$dist,$query_line);
1559                                }
1560                        }
1561                }
1562                if ($extras_option['do_change_uri']){
1563                        if (!empty($extras_option['before_uri']) && !empty($extras_option['after_uri'])){
1564                                $org =  $extras_option['before_uri'];
1565                                $org =  str_replace('/','\\/',$org);
1566                                $src = '/' . $org . '/';
1567                                $dist = $extras_option['after_uri'];
1568                                if(preg_match($src,$query_line)){
1569                                        $query_line = preg_replace($src,$dist,$query_line);
1570                                }
1571                        }
1572                }
1573                return $query_line;
1574        }
1575        function is_mbstring(){
1576                return function_exists('mb_convert_encoding');
1577        }
1578               
1579
1580}
1581
1582function wpdbBackup_init() {
1583        global $mywpdbbackup;
1584        $mywpdbbackup = new wpdbBackup();       
1585}
1586
1587add_action('plugins_loaded', 'wpdbBackup_init');
1588?>
Note: See TracBrowser for help on using the repository browser.