function DBError($file, $line, $friendly = false)
 {
     $this->Log_Event(WPONLINEBACKUP_EVENT_ERROR, __('A database operation failed.', 'wponlinebackup') . PHP_EOL . __('Please try reinstalling the plugin - in most cases this will repair the database.', 'wponlinebackup') . PHP_EOL . __('Please contact support if the issue persists, providing the complete event log for the activity. Diagnostic information follows:', 'wponlinebackup') . PHP_EOL . PHP_EOL . 'Failed at: ' . $file . '(' . $line . ')' . PHP_EOL . WPOnlineBackup::Get_WPDB_Last_Error());
     if ($friendly === false) {
         $friendly = __('A database operation failed.', 'wponlinebackup');
     }
     return $friendly;
 }
 function Get_Temp()
 {
     return realpath(WPOnlineBackup::Get_Temp_Raw());
 }
 function Backup_Table()
 {
     global $wpdb;
     // We backup each table and jump back to bootstrap after each table for a forced update
     // We may improve this to work same as files in future and loop forever in here and decide on our own forced updates
     while ($this->job['progress'] != 100) {
         $where = array();
         if (count($this->job['primary'])) {
             // We have a primary or unique key, add an order by clause
             $extra = ' ORDER BY ' . WPOnlineBackup_Backup_Tables::Implode_Backquote(' ASC, ', $this->job['primary']) . ' ASC';
             // Calculate the where clause based on the key if we already have the table information
             // If we don't have the table information yet, we don't give a WHERE so we can get the first set of rows
             if (!is_null($this->job['total'])) {
                 $previous = array();
                 // We search for records with ID higher than the last id.
                 // For multi-column, we check for where the first ID is higher, or the first ID is the same and the second ID is higher, and so on
                 foreach ($this->job['primary'] as $index => $column) {
                     $value = $this->job['last_id'][$index];
                     // Calls _real_escape if it exists - escape() seems to call _weak_escape() instead
                     $wpdb->escape_by_ref($value);
                     if (count($previous)) {
                         $where[] = '(' . implode(' AND ', $previous) . ' AND `' . $column . '` > \'' . $value . '\')';
                     } else {
                         $where[] = '`' . $column . '` > \'' . $value . '\'';
                     }
                     $previous[] = '`' . $column . '` = \'' . $value . '\'';
                 }
                 if (count($where) > 1) {
                     $where = array('(' . implode(' OR ', $where) . ')');
                 }
             }
             // When using a key, we don't need a start offset, as we calculate it based on IDs
             $start = '';
         } else {
             $extra = '';
             // No primary or unique key available, so we failback to setting a start offset
             if (!is_null($this->job['total'])) {
                 $start = $this->job['done'] . ', ';
             } else {
                 $start = '';
             }
         }
         if ($is_comments = preg_match($this->multisite_prefix_regex . 'comments$#', $this->job['table'])) {
             if ($this->WPOnlineBackup->Get_Setting('ignore_spam_comments')) {
                 $where[] = '`comment_approved` <> \'spam\'';
             }
             if ($this->WPOnlineBackup->Get_Setting('ignore_trash_comments')) {
                 $where[] = '`comment_approved` <> \'trash\'';
             }
         } else {
             if ($this->job['table'] == $this->db_prefix . 'options') {
                 // Remove this option - it will trigger our tables to be created on restore
                 $where[] = '`option_name` <> \'wponlinebackup_check_tables\'';
             }
         }
         $where = implode(' AND ', $where);
         if ($where) {
             $where = ' WHERE ' . $where;
         }
         if (is_null($this->job['total'])) {
             $this->progress['message'] = sprintf(__('Backing up %s...', 'wponlinebackup'), $this->job['table']);
             $drop = 'DROP TABLE IF EXISTS `' . $this->job['table'] . '`;' . WPONLINEBACKUP_EOL . WPONLINEBACKUP_EOL;
             // Table information doesn't exist, so let's gather it, first by getting the CREATE TABLE dump
             $wpdb->query('SET sql_quote_show_create = 1');
             $create = $wpdb->get_var('SHOW CREATE TABLE `' . $this->job['table'] . '`', 1);
             // SHOW CREATE TABLE should always return a row, so 0 rows (null) or error (null) both are considered an error
             if (is_null($create)) {
                 // Failed to gather table information - report, and skip the table
                 $this->bootstrap->Log_Event(WPONLINEBACKUP_EVENT_ERROR, sprintf(__('Failed to retrieve information for table \'%s\': %s. The table will be skipped.', 'wponlinebackup'), $this->job['table'], WPOnlineBackup::Get_WPDB_Last_Error()));
                 $this->job['progress'] = 100;
                 // Breaking will throw us all the way out back into bootstrap for a forced update that will prevent the event log duplicating
                 break;
             }
             // Normalise line-endings
             $create = preg_replace('/\\r\\n?|\\n/', WPONLINEBACKUP_EOL, $create);
             $create .= ';' . WPONLINEBACKUP_EOL . WPONLINEBACKUP_EOL;
             $this->progress['rsize'] += strlen($create);
             if (($ret = $this->stream->Write_Stream($drop . $create)) !== true) {
                 return $ret;
             }
             // Get the total number of rows in the table, so we can provide progress information if required
             $this->job['total'] = $wpdb->get_var('SELECT COUNT(*) FROM `' . $this->job['table'] . '`' . $where);
             // SELECT COUNT(*) should always return a row, so 0 rows (null) or error (null) both are considered an error
             if (is_null($this->job['total'])) {
                 // Failed to gather row count - report, and skip the table
                 $this->bootstrap->Log_Event(WPONLINEBACKUP_EVENT_ERROR, sprintf(__('Failed to retrieve row count for table \'%s\': %s. The table will be skipped.', 'wponlinebackup'), $this->job['table'], WPOnlineBackup::Get_WPDB_Last_Error()));
                 $this->job['progress'] = 100;
                 // Breaking will throw us all the way out back into bootstrap for a forced update that will prevent the event log duplicating
                 break;
             }
             $this->bootstrap->Tick();
         }
         $fields = WPOnlineBackup_Backup_Tables::Implode_Backquote(',', $this->job['fields']);
         // Begin retrieving data
         if (($result = $this->Query($fields, $this->job['table'], $where, $extra, $start)) === false) {
             // Failure is logged inside Query()
             $this->job['progress'] = 100;
             // Breaking here throws back to bootstrap for a forced update - this will prevent duplicating the event log entries Query() wrote
             break;
         }
         $this->bootstrap->Tick();
         // Create a fully escaped insert statement
         $insert = '';
         $row_count = 0;
         $insert_size = 0;
         while (false !== ($next_row = $this->Fetch_Row($result))) {
             $row = $next_row;
             $values = array();
             $row_count++;
             foreach ($row as $index => $value) {
                 $insert_size += strlen($value);
                 // If we're not the first row and our insert has got too big, write the insert and start another
                 // This prevents our insert getting rediculously big
                 if ($row_count > 1 && $insert_size > $this->max_block_size) {
                     $row_count--;
                     break 2;
                 }
                 if (is_null($value)) {
                     $value = 'NULL';
                 } else {
                     if (!$this->Requires_Quotes($value)) {
                     } else {
                         // escape_by_ref uses _real_escape - preferred. escape() appears to only use _weak_escape()
                         $wpdb->escape_by_ref($value);
                         $value = '\'' . $value . '\'';
                     }
                 }
                 $values[] = $value;
             }
             $insert .= ($row_count == 1 ? 'INSERT INTO `' . $this->job['table'] . '` (' . $fields . ') VALUES' . WPONLINEBACKUP_EOL : ',' . WPONLINEBACKUP_EOL) . '(' . implode(',', $values) . ')';
         }
         unset($values);
         unset($value);
         $this->Free_Result($result);
         // If 0 rows were returned, we reached the end of the dataset
         // We couldn't use num_rows or anything as we may be an unbuffered query result
         if ($row_count == 0) {
             $this->job['progress'] = 100;
             break;
         }
         // Finish the statement
         $insert .= ';' . WPONLINEBACKUP_EOL . WPONLINEBACKUP_EOL;
         $this->job['done'] += $row_count;
         if ($this->job['done'] >= $this->job['total']) {
             $this->job['progress'] = 99;
         } else {
             $this->job['progress'] = floor($this->job['done'] * 99 / $this->job['total']);
             if ($this->job['progress'] >= 100) {
                 $this->job['progress'] = 99;
             }
         }
         $this->progress['message'] = sprintf(__('Backing up %s; %d of %d rows...', 'wponlinebackup'), $this->job['table'], $this->job['done'], $this->job['total']);
         // If we are tracking using a key, update the last_id fields
         if (count($this->job['primary'])) {
             foreach ($this->job['primary'] as $index => $column) {
                 $this->job['last_id'][$index] = $row[array_search($column, $this->job['fields'])];
             }
         }
         // Add to the dump
         $this->progress['rsize'] += strlen($insert);
         if (($ret = $this->stream->Write_Stream($insert)) !== true) {
             return $ret;
         }
         $this->bootstrap->Tick();
     }
     return true;
 }
    function Print_Events_Table()
    {
        global $wpdb;
        $activity_id = array_key_exists('activity', $_GET) ? strval($_GET['activity']) : 0;
        $wpdb->escape_by_ref($activity_id);
        $activity = $wpdb->get_row('SELECT activity_id, start, end, type, media, comp, errors, warnings, compressed, encrypted, ' . 'bsize, bcount, rsize, rcount ' . 'FROM `' . $wpdb->prefix . 'wponlinebackup_activity_log` ' . 'WHERE activity_id = \'' . $activity_id . '\'', ARRAY_A);
        if (is_null($activity)) {
            ?>
<p style="text-align: center; padding: 12px"><img src="<?php 
            echo WPONLINEBACKUP_URL;
            ?>
/images/error.png" style="width: 16px; height: 16px; vertical-align: middle" alt="">&nbsp;<i><?php 
            _e('The specified activity no longer exists. There are no events to show.', 'wponlinebackup');
            ?>
</i></p>
<?php 
            return;
        }
        ?>
<p>
	<b>Activity ID:</b> <?php 
        echo $activity['activity_id'];
        if ($activity['type'] == WPONLINEBACKUP_ACTIVITY_BACKUP) {
            $icon = array('user.png', __('Manual Backup', 'wponlinebackup'));
        } else {
            if ($activity['type'] == WPONLINEBACKUP_ACTIVITY_AUTO_BACKUP) {
                $icon = array('date.png', __('Scheduled Backup', 'wponlinebackup'));
            } else {
                if ($activity['type'] == WPONLINEBACKUP_ACTIVITY_DECRYPT) {
                    $icon = array('key.png', __('Decrypt', 'wponlinebackup'));
                } else {
                    $icon = array('help.png', __('Unknown', 'wponlinebackup'));
                }
            }
        }
        if (!is_null($icon)) {
            ?>
<br>
	<b>Activity Type:</b> <img src="<?php 
            echo WPONLINEBACKUP_URL;
            ?>
/images/<?php 
            echo $icon[0];
            ?>
" style="width: 16px; height: 16px; vertical-align: middle">&nbsp;<?php 
            echo $icon[1];
        }
        $settings = array();
        switch ($activity['media']) {
            case WPONLINEBACKUP_MEDIA_DOWNLOAD:
                $settings[] = array('cd.png', __('Local', 'wponlinebackup'));
                break;
            case WPONLINEBACKUP_MEDIA_EMAIL:
                $settings[] = array('email.png', __('Emailed', 'wponlinebackup'));
                break;
            case WPONLINEBACKUP_MEDIA_ONLINE:
                $settings[] = array('transmit.png', __('Sent to Online Vault', 'wponlinebackup'));
                break;
        }
        if ($activity['compressed']) {
            $settings[] = array('compress.png', __('Compressed', 'wponlinebackup'));
        }
        if ($activity['encrypted']) {
            $settings[] = array('lock_small.png', __('Encrypted', 'wponlinebackup'));
        }
        if (count($settings)) {
            ?>
<br>
	<b>Settings:</b> <?php 
            end($settings);
            $last = key($settings);
            foreach ($settings as $key => $icon) {
                ?>
<img src="<?php 
                echo WPONLINEBACKUP_URL;
                ?>
/images/<?php 
                echo $icon[0];
                ?>
" style="width: 16px; height: 16px; vertical-align: middle">&nbsp;<?php 
                echo $icon[1];
                if ($key != $last) {
                    ?>
, <?php 
                }
            }
        }
        ?>
</p>
<p>
	<b>Completion:</b> <?php 
        switch ($activity['comp']) {
            //			case WPONLINEBACKUP_COMP_UNEXPECTED:
            default:
                $message = array('exclamation.png', 'A00', __('Unexpected stop', 'wponlinebackup'));
                break;
            case WPONLINEBACKUP_COMP_RUNNING:
                $message = array('ajax-loader.gif', '000', __('Running...', 'wponlinebackup'));
                break;
            case WPONLINEBACKUP_COMP_SUCCESSFUL:
                $message = array('accept.png', '0A0', $activity['warnings'] ? sprintf(_n('Successful (%d warning)', 'Successful (%d warnings)', $activity['warnings'], 'wponlinebackup'), $activity['warnings']) : __('Successful', 'wponlinebackup'));
                break;
            case WPONLINEBACKUP_COMP_PARTIAL:
                $message = array('error.png', 'A80', $activity['errors'] ? sprintf(_n('Partial (%d error)', 'Partial (%d errors)', $activity['errors'], 'wponlinebackup'), $activity['errors']) : __('Partial', 'wponlinebackup'));
                break;
            case WPONLINEBACKUP_COMP_STOPPED:
                $message = array('exclamation.png', 'A00', __('Stopped', 'wponlinebackup'));
                break;
            case WPONLINEBACKUP_COMP_FAILED:
            case WPONLINEBACKUP_COMP_TIMEOUT:
            case WPONLINEBACKUP_COMP_SLOWTIMEOUT:
                $message = array('exclamation.png', 'A00', __('Failed', 'wponlinebackup'));
                break;
            case WPONLINEBACKUP_COMP_MEMORY:
            case WPONLINEBACKUP_COMP_SLOWMEMORY:
                $message = array('exclamation.png', 'A00', __('Low Memory', 'wponlinebackup'));
                break;
            case WPONLINEBACKUP_COMP_MAINTENANCE:
                $message = array('exclamation.png', 'A00', __('Maintenance', 'wponlinebackup'));
                break;
        }
        ?>
<img src="<?php 
        echo WPONLINEBACKUP_URL;
        ?>
/images/<?php 
        echo $message[0];
        ?>
" style="width: 16px; height: 16px; vertical-align: middle" alt="">&nbsp;<b style="color: #<?php 
        echo $message[1];
        ?>
"><?php 
        echo $message[2];
        ?>
</b>
</p>
<p>
	<b>Backup Size:</b> <?php 
        printf(_n('%s (%d file)', '%s (%d files)', $activity['bcount'], 'wponlinebackup'), WPOnlineBackup_Formatting::Fix_B($activity['bsize']), $activity['bcount']);
        ?>
<br>
	<b>Total Size:</b> <?php 
        printf(_n('%s (%d file)', '%s (%d files)', $activity['rcount'], 'wponlinebackup'), WPOnlineBackup_Formatting::Fix_B($activity['rsize']), $activity['rcount']);
        ?>
</p>
<p>
	<b>Start Time:</b> <?php 
        echo htmlentities(date_i18n(_x('jS M Y g.i.s A', 'Event log activity start time', 'wponlinebackup'), WPOnlineBackup::Convert_Unixtime_To_Wordpress_Unixtime($activity['start'])), ENT_QUOTES, 'UTF-8');
        ?>
<br>
	<b>End Time:</b> <?php 
        if (is_null($activity['end'])) {
            ?>
<i><?php 
            echo __('N/A', 'wponlinebackup');
            ?>
</i><?php 
        } else {
            echo htmlentities(date_i18n(_x('jS M Y g.i.s A', 'Event log activity end time', 'wponlinebackup'), WPOnlineBackup::Convert_Unixtime_To_Wordpress_Unixtime($activity['end'])), ENT_QUOTES, 'UTF-8');
        }
        ?>

</p>
<table class="widefat" cellspacing="0">
<thead>
<tr>
<th width="15%" scope="col" id="time" class="manage-column column-time" style=""><?php 
        echo __('Time', 'wponlinebackup');
        ?>
</th>
<th width="12%" scope="col" id="type" class="manage-column column-type" style=""><?php 
        echo __('Type', 'wponlinebackup');
        ?>
</th>
<th scope="col" id="event" class="manage-column column-event" style=""><?php 
        echo __('Event', 'wponlinebackup');
        ?>
</th>
</tr>
</thead>
<tfoot>
<tr>
<th width="15%" scope="col" class="manage-column column-time" style=""><?php 
        echo __('Time', 'wponlinebackup');
        ?>
</th>
<th width="12%" scope="col" class="manage-column column-type" style=""><?php 
        echo __('Type', 'wponlinebackup');
        ?>
</th>
<th scope="col" class="manage-column column-event" style=""><?php 
        echo __('Event', 'wponlinebackup');
        ?>
</th>
</tr>
</tfoot>
<tbody>
<?php 
        $result = $wpdb->get_results('SELECT time, type, event ' . 'FROM `' . $wpdb->prefix . 'wponlinebackup_event_log` ' . 'WHERE activity_id = \'' . $activity_id . '\' ' . 'ORDER BY time DESC, event_id DESC', ARRAY_A);
        // Display the event logs, or an empty message
        if (count($result) == 0) {
            ?>
<tr>
<td colspan="8" style="text-align: center; padding: 12px"><img src="<?php 
            echo WPONLINEBACKUP_URL;
            ?>
/images/information.png" style="width: 16px; height: 16px; vertical-align: middle" alt="">&nbsp;<i><?php 
            _e('The Event Log for this activity is currently empty.', 'wponlinebackup');
            ?>
</i></td>
</tr>
<?php 
        } else {
            $c = 0;
            foreach ($result as $event) {
                ?>
<tr<?php 
                if ($c++ % 2 == 0) {
                    ?>
 class="alternate"<?php 
                }
                ?>
 valign="top">
<td class="column-time"><?php 
                echo htmlentities(date_i18n(_x('jS M Y g.i.s A', 'Event log entry time', 'wponlinebackup'), WPOnlineBackup::Convert_Unixtime_To_Wordpress_Unixtime($event['time'])), ENT_QUOTES, 'UTF-8');
                ?>
</td>
<td class="column-type"><?php 
                switch ($event['type']) {
                    //					case WPONLINEBACKUP_EVENT_INFORMATION:
                    default:
                        $type = array('information.png', __('Information', 'wponlinebackup'));
                        break;
                    case WPONLINEBACKUP_EVENT_WARNING:
                        $type = array('error.png', __('Warning', 'wponlinebackup'));
                        break;
                    case WPONLINEBACKUP_EVENT_ERROR:
                        $type = array('exclamation.png', __('Error', 'wponlinebackup'));
                        break;
                }
                ?>
<img src="<?php 
                echo WPONLINEBACKUP_URL;
                ?>
/images/<?php 
                echo $type[0];
                ?>
" style="width: 16px; height: 16px; vertical-align: middle" alt="">&nbsp;<?php 
                echo htmlentities($type[1], ENT_QUOTES);
                ?>
</td>
<td class="column-event"><?php 
                echo preg_replace('/(?:\\n|\\r\\n?)/', '<br>' . PHP_EOL, htmlentities($event['event'], ENT_QUOTES));
                ?>
</td>
</tr>
<?php 
            }
        }
        ?>
</tbody>
</table>
<?php 
    }