/**
  * Make sure setting a custom path + database dump filename correctly sets the database dump filepath
  *
  * @access public
  */
 public function testCustomDatabaseDumpPath()
 {
     $this->backup->set_path(WP_CONTENT_DIR . '/custom');
     $this->backup->set_database_dump_filename('dump.sql');
     $this->assertEquals(HM_Backup::conform_dir(WP_CONTENT_DIR . '/custom/dump.sql'), $this->backup->get_database_dump_filepath());
     $this->backup->dump_database();
     $this->assertFileExists($this->backup->get_database_dump_filepath());
 }
Example #2
0
/**
 * Display a html list of files
 *
 * @param HMBKP_Scheduled_Backup $schedule
 * @param mixed                  $excludes    (default: null)
 * @param string                 $file_method (default: 'get_included_files')
 * @return void
 */
function hmbkp_file_list(HMBKP_Scheduled_Backup $schedule, $excludes = null, $file_method = 'get_included_files')
{
    if (!is_null($excludes)) {
        $schedule->set_excludes($excludes);
    }
    $exclude_string = $schedule->exclude_string('regex');
    ?>

	<ul class="hmbkp_file_list code">

		<?php 
    foreach ($schedule->get_files() as $file) {
        if (!is_null($excludes) && strpos($file, str_ireplace($schedule->get_root(), '', $schedule->get_path())) !== false) {
            continue;
        }
        // Skip dot files, they should only exist on versions of PHP between 5.2.11 -> 5.3
        if (method_exists($file, 'isDot') && $file->isDot()) {
            continue;
        }
        // Show only unreadable files
        if ($file_method === 'get_unreadable_files' && @realpath($file->getPathname()) && $file->isReadable()) {
            continue;
        } elseif ($file_method !== 'get_unreadable_files' && (!@realpath($file->getPathname()) || !$file->isReadable())) {
            continue;
        }
        // Show only included files
        if ($file_method === 'get_included_files') {
            if ($exclude_string && preg_match('(' . $exclude_string . ')', str_ireplace(trailingslashit($schedule->get_root()), '', HM_Backup::conform_dir($file->getPathname())))) {
                continue;
            }
        }
        // Show only excluded files
        if ($file_method === 'get_excluded_files') {
            if (!$exclude_string || !preg_match('(' . $exclude_string . ')', str_ireplace(trailingslashit($schedule->get_root()), '', HM_Backup::conform_dir($file->getPathname())))) {
                continue;
            }
        }
        if (@realpath($file->getPathname()) && !$file->isReadable() && $file->isDir()) {
            ?>

				<li title="<?php 
            echo esc_attr(HM_Backup::conform_dir(trailingslashit($file->getPathName())));
            ?>
"><?php 
            echo esc_html(ltrim(trailingslashit(str_ireplace(HM_Backup::conform_dir(trailingslashit($schedule->get_root())), '', HM_Backup::conform_dir($file->getPathName()))), '/'));
            ?>
</li>

			<?php 
        } else {
            ?>

				<li title="<?php 
            echo esc_attr(HM_Backup::conform_dir($file->getPathName()));
            ?>
"><?php 
            echo esc_html(ltrim(str_ireplace(HM_Backup::conform_dir(trailingslashit($schedule->get_root())), '', HM_Backup::conform_dir($file->getPathName())), '/'));
            ?>
</li>

			<?php 
        }
    }
    ?>

	</ul>

<?php 
}
 /**
  * Get the total filesize for a given file or directory
  *
  * If $file is a file then just return the result of `filesize()`.
  * If $file is a directory then schedule a recursive filesize scan.
  *
  * @param SplFileInfo $file			The file or directory you want to know the size of
  * @param bool $skip_excluded_files	Skip excluded files when calculating a directories total size
  * @return int 						The total of the file or directory
  */
 public function filesize(SplFileInfo $file, $skip_excluded_files = false)
 {
     // Skip missing or unreadable files
     if (!file_exists($file->getPathname()) || !@realpath($file->getPathname()) || !$file->isReadable()) {
         return false;
     }
     // If it's a file then just pass back the filesize
     if ($file->isFile() && $file->isReadable()) {
         return $file->getSize();
     }
     // If it's a directory then pull it from the cached filesize array
     if ($file->isDir()) {
         // If we haven't calculated the site size yet then kick it off in a thread
         $directory_sizes = get_transient('hmbkp_directory_filesizes');
         if (!is_array($directory_sizes)) {
             if (!$this->is_site_size_being_calculated()) {
                 // Mark the filesize as being calculated
                 set_transient('hmbkp_directory_filesizes_running', true, HOUR_IN_SECONDS);
                 // Schedule a Backdrop task to trigger a recalculation
                 $task = new HM_Backdrop_Task(array($this, 'recursive_filesize_scanner'));
                 $task->schedule();
             }
             return;
         }
         $current_pathname = trailingslashit($file->getPathname());
         $root = trailingslashit($this->get_root());
         foreach ($directory_sizes as $path => $size) {
             // Remove any files that aren't part of the current tree
             if (false === strpos($path, $current_pathname)) {
                 unset($directory_sizes[$path]);
             }
         }
         if ($skip_excluded_files) {
             $excludes = $this->exclude_string('regex');
             foreach ($directory_sizes as $path => $size) {
                 // Skip excluded files if we have excludes
                 if ($excludes && preg_match('(' . $excludes . ')', str_ireplace($root, '', HM_Backup::conform_dir($path)))) {
                     unset($directory_sizes[$path]);
                 }
             }
         }
         // Directory size is now just a sum of all files across all sub directories
         return array_sum($directory_sizes);
     }
 }
Example #4
0
/**
 * Handles changes in the defined Constants
 * that users can define to control advanced
 * settings
 */
function hmbkp_constant_changes()
{
    // If a custom backup path has been set or changed
    if (defined('HMBKP_PATH') && HMBKP_PATH && HM_Backup::conform_dir(HMBKP_PATH) !== ($from = HM_Backup::conform_dir(get_option('hmbkp_path')))) {
        hmbkp_path_move($from, HMBKP_PATH);
    }
    // If a custom backup path has been removed
    if (defined('HMBKP_PATH') && !HMBKP_PATH || !defined('HMBKP_PATH') && hmbkp_path_default() !== ($from = HM_Backup::conform_dir(get_option('hmbkp_path')))) {
        hmbkp_path_move($from, hmbkp_path_default());
    }
    // If the custom path has changed and the new directory isn't writable
    if (defined('HMBKP_PATH') && HMBKP_PATH && !is_writable(HMBKP_PATH) && get_option('hmbkp_path') === HMBKP_PATH && is_dir(HMBKP_PATH)) {
        hmbkp_path_move(HMBKP_PATH, hmbkp_path_default());
    }
}
Example #5
0
/**
 * Send the download file to the browser and then redirect back to the backups page
 */
function hmbkp_request_download_backup()
{
    check_admin_referer('hmbkp_download_backup', 'hmbkp_download_backup_nonce');
    if (!file_exists(sanitize_text_field(base64_decode($_GET['hmbkp_backup_archive'])))) {
        return;
    }
    $url = str_replace(HM_Backup::conform_dir(HM_Backup::get_home_path()), home_url(), trailingslashit(dirname(sanitize_text_field(base64_decode($_GET['hmbkp_backup_archive']))))) . urlencode(pathinfo(sanitize_text_field(base64_decode($_GET['hmbkp_backup_archive'])), PATHINFO_BASENAME));
    global $is_apache;
    if ($is_apache) {
        HMBKP_Path::get_instance()->protect_path('reset');
        $url = add_query_arg('key', HMBKP_SECURE_KEY, $url);
    }
    wp_safe_redirect($url, 303);
    die;
}
Example #6
0
 /**
  * Calculate the size of the backup
  *
  * Doesn't account for
  * compression
  *
  * @access public
  * @param bool $cached Whether to return from cache
  * @return string
  */
 public function get_filesize($cached = true)
 {
     $filesize = 0;
     if ($cached) {
         // Check if we have the filesize in the cache
         $filesize = get_transient('hmbkp_schedule_' . $this->get_id() . '_filesize');
         // If we do and it's not still calculating then return it straight away
         if ($filesize && $filesize !== 'calculating') {
             return $filesize;
         }
         // If the filesize is calculating in another thread then we should wait for it to finish
         if ($filesize === 'calculating') {
             global $wpdb;
             $counter = 1;
             // Keep checking the cached filesize to see if the other thread is finished
             while ('calculating' === ($filesize = $wpdb->get_var("SELECT option_value FROM {$wpdb->options} WHERE option_name = '_transient_hmbkp_schedule_" . $this->get_id() . "_filesize'"))) {
                 // Check once every 10 seconds
                 sleep(10);
                 // Only run for a maximum of 5 minutes (30*10)
                 if ($counter === 30) {
                     break;
                 }
                 $counter++;
             }
             // If we have the filesize then return it
             if ($filesize && $filesize !== 'calculating') {
                 return $filesize;
             }
         }
     }
     // If we don't have it in cache then mark it as calculating
     set_transient('hmbkp_schedule_' . $this->get_id() . '_filesize', 'calculating', time() + HOUR_IN_SECONDS);
     // Don't include database if file only
     if ($this->get_type() != 'file') {
         global $wpdb;
         $res = $wpdb->get_results('SHOW TABLE STATUS FROM `' . DB_NAME . '`', ARRAY_A);
         foreach ($res as $r) {
             $filesize += (double) $r['Data_length'];
         }
     }
     // Don't include files if database only
     if ($this->get_type() != 'database') {
         // Get rid of any cached filesizes
         clearstatcache();
         $excludes = $this->exclude_string('regex');
         foreach ($this->get_files() as $file) {
             // Skip dot files, they should only exist on versions of PHP between 5.2.11 -> 5.3
             if (method_exists($file, 'isDot') && $file->isDot()) {
                 continue;
             }
             if (!@realpath($file->getPathname()) || !$file->isReadable()) {
                 continue;
             }
             // Excludes
             if ($excludes && preg_match('(' . $excludes . ')', str_ireplace(trailingslashit($this->get_root()), '', HM_Backup::conform_dir($file->getPathname())))) {
                 continue;
             }
             $filesize += (double) $file->getSize();
         }
     }
     // Cache for a day
     set_transient('hmbkp_schedule_' . $this->get_id() . '_filesize', $filesize, time() + DAY_IN_SECONDS);
     return $filesize;
 }
Example #7
0
/**
 * Send the download file to the browser and
 * then redirect back to the backups page
 */
function hmbkp_request_download_backup()
{
    global $is_apache;
    if (empty($_GET['hmbkp_download_backup']) || !check_admin_referer('hmbkp-download_backup') || !file_exists(sanitize_text_field(base64_decode($_GET['hmbkp_download_backup'])))) {
        return;
    }
    $url = str_replace(HM_Backup::conform_dir(HM_Backup::get_home_path()), home_url(), trailingslashit(dirname(sanitize_text_field(base64_decode($_GET['hmbkp_download_backup']))))) . urlencode(pathinfo(sanitize_text_field(base64_decode($_GET['hmbkp_download_backup'])), PATHINFO_BASENAME));
    if ($is_apache) {
        // Force the .htaccess to be rebuilt
        if (file_exists(hmbkp_path() . '/.htaccess')) {
            unlink(hmbkp_path() . '/.htaccess');
        }
        hmbkp_path();
        $url = add_query_arg('key', HMBKP_SECURE_KEY, $url);
    }
    wp_redirect($url, 303);
    die;
}
					</td>

					<td></td>

				</tr>

			</thead>

			<tbody>

				<?php 
    foreach ($files as $size => $file) {
        $is_excluded = $is_unreadable = false;
        // Check if the file is excluded
        if ($exclude_string && preg_match('(' . $exclude_string . ')', str_ireplace(trailingslashit($schedule->get_root()), '', HM_Backup::conform_dir($file->getPathname())))) {
            $is_excluded = true;
        }
        // Skip unreadable files
        if (!@realpath($file->getPathname()) || !$file->isReadable()) {
            $is_unreadable = true;
        }
        ?>

					<tr>

						<td>

							<?php 
        if ($is_unreadable) {
            ?>
 public function testMixedSlashes()
 {
     $this->assertEquals(HM_Backup::conform_dir('\\/one\\//\\two\\/\\three'), $this->dir);
 }
 /**
  * Recursively scans a directory to calculate the total filesize
  *
  * @param string $directory		The directory to scan
  * @param bool $ignore_excludes	Whether or not to include excluded files in the total filesize calculation
  * @return int $total_filesize	The total filesize of all files in all subdirectories
  */
 public function recursive_directory_filesize_scanner($directory, $ignore_excludes = true)
 {
     if (!is_dir($directory)) {
         return $total_filesize;
     }
     $handle = opendir($directory);
     if (!$handle) {
         return $total_filesize;
     }
     $excludes = $this->exclude_string('regex');
     $transient_filesize_key = $this->get_transient_key($directory);
     $transient_running_key = $this->get_transient_key('running_' . $directory);
     if (!$ignore_excludes) {
         $transient_filesize_key = $this->get_transient_key($excludes . $directory);
         $transient_running_key = $this->get_transient_key('running_' . $excludes . $directory);
     }
     // Use the cached directory size if available
     $directory_size = get_transient($transient_filesize_key);
     if ($directory_size !== false) {
         delete_option($transient_running_key);
         return $directory_size;
     }
     update_option($transient_running_key, true);
     $total_filesize = 0;
     $files = array();
     clearstatcache();
     while ($file_handle = readdir($handle)) {
         // Ignore current dir and containing dir
         if ($file_handle === '.' || $file_handle === '..') {
             continue;
         }
         $file = new SplFileInfo(HM_Backup::conform_dir(trailingslashit($directory) . $file_handle));
         // Skip unreadable files
         if (!@realpath($file->getPathname()) || !$file->isReadable()) {
             continue;
         }
         // Skip excluded files if we have excludes
         if (!$ignore_excludes && $excludes && preg_match('(' . $excludes . ')', str_ireplace(trailingslashit($this->get_root()), '', HM_Backup::conform_dir($file->getPathname())))) {
             continue;
         }
         $total_filesize += $file->getSize();
         // We need to recursively calculate the size of all files in a subdirectory
         if ($file->isDir()) {
             $total_filesize += $this->recursive_directory_filesize_scanner($file->getPathname(), $ignore_excludes);
         }
     }
     closedir($handle);
     // If we have a filesize then let's cache it
     if ($total_filesize !== false) {
         set_transient($transient_filesize_key, (string) $total_filesize, WEEK_IN_SECONDS);
     }
     delete_option($transient_running_key);
     return $total_filesize;
 }
Example #11
0
/**
 *
 * @param null $pathname
 */
function hmbkp_recalculate_directory_filesize($pathname = null)
{
    if (!$pathname && (!isset($_GET['hmbkp_recalculate_directory_filesize']) || !check_admin_referer('hmbkp-recalculate_directory_filesize'))) {
        return;
    }
    $schedule = new HMBKP_Scheduled_Backup(sanitize_text_field($_GET['hmbkp_schedule_id']));
    if (!$pathname) {
        $directory = sanitize_text_field($_GET['hmbkp_recalculate_directory_filesize']);
    } else {
        $directory = $pathname;
    }
    // Delete the cached directory size
    // TODO should use $schedule->get_transient_key
    delete_transient($schedule->get_transient_key($directory));
    $handle = opendir($directory);
    while ($file_handle = readdir($handle)) {
        // Ignore current dir and containing dir
        if ($file_handle === '.' || $file_handle === '..') {
            continue;
        }
        $file = HM_Backup::conform_dir(trailingslashit($directory) . $file_handle);
        // Delete all sub directories
        if (is_dir($file)) {
            delete_transient($schedule->get_transient_key($file));
            hmbkp_recalculate_directory_filesize($file);
        }
    }
    closedir($handle);
    $parent_directory = dirname($directory);
    // Delete the cached filesize of all parents as well
    while ($schedule->get_root() !== $parent_directory) {
        delete_transient($schedule->get_transient_key($parent_directory));
        $parent_directory = dirname($parent_directory);
    }
    if (!$pathname) {
        $url = add_query_arg(array('action' => 'hmbkp_edit_schedule', 'hmbkp_panel' => 'hmbkp_edit_schedule_excludes'), hmbkp_get_settings_url());
        if (isset($_GET['hmbkp_directory_browse'])) {
            $url = add_query_arg('hmbkp_directory_browse', sanitize_text_field($_GET['hmbkp_directory_browse']), $url);
        }
        wp_safe_redirect($url, '303');
        die;
    }
}