| Server IP : 216.238.66.20 / Your IP : 216.73.216.199 Web Server : nginx/1.30.4 System : Linux woropds 5.15.0-187-generic #197-Ubuntu SMP Fri Jul 17 19:17:01 UTC 2026 x86_64 User : root ( 0) PHP Version : 8.2.33 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : OFF | Perl : OFF | Python : OFF | Sudo : OFF | Pkexec : OFF Directory : /var/www/sweetheart.mx/htdocs/wp-content/plugins/backwpup/inc/ |
Upload File : |
<?php
/**
* BackWPup_Destination_Downloader.
*
* @since 3.6.0
*/
use Inpsyde\Restore\Api\Controller\DecryptController;
use Inpsyde\Restore\Api\Module\Decryption\Exception\DecryptException;
use function Inpsyde\BackWPup\Infrastructure\Restore\restore_container;
/**
* Class BackWPup_Destination_Downloader.
*
* @since 3.6.0
*/
class BackWPup_Destination_Downloader {
public const CAPABILITY = 'backwpup_backups_download';
public const STATE_DOWNLOADING = 'downloading';
public const STATE_ERROR = 'error';
public const STATE_DONE = 'done';
/**
* Downloader data object.
*
* @var \BackWpUp_Destination_Downloader_Data
*/
private $data;
/**
* Destination downloader service.
*
* @var \BackWPup_Destination_Downloader_Interface
*/
private $destination;
/**
* BackWPup_Downloader constructor.
*
* @param \BackWpUp_Destination_Downloader_Data $data Download data.
* @param \BackWPup_Destination_Downloader_Interface $destination Destination service.
*/
public function __construct(
BackWpUp_Destination_Downloader_Data $data,
BackWPup_Destination_Downloader_Interface $destination
) {
$this->data = $data;
$this->destination = $destination;
}
/**
* Download file via ajax.
*
* @return void
*/
public static function download_by_ajax() {
$dest = (string) filter_input( INPUT_GET, 'destination' );
if ( ! $dest ) {
return;
}
$job_id = (int) filter_input( INPUT_GET, 'jobid', FILTER_SANITIZE_NUMBER_INT );
if ( ! $job_id ) {
return;
}
$file = (string) filter_input( INPUT_GET, 'file' );
$file_local = (string) filter_input( INPUT_GET, 'local_file' );
if ( ! $file || ! $file_local ) {
return;
}
set_time_limit( 0 );
// Set up eventsource headers.
header( 'Content-Type: text/event-stream' );
header( 'Cache-Control: no-cache' );
header( 'X-Accel-Buffering: no' );
header( 'Content-Encoding: none' );
// 2KB padding for IE.
echo esc_html( ':' . str_repeat( ' ', 2048 ) . "\n\n" );
// Ensure we're not buffered.
wp_ob_end_flush_all();
flush();
/**
* Destination handler.
*
* @var \BackWPup_Destinations $dest_class
*/
$dest_class = BackWPup::get_destination( $dest );
$dest_class->file_download(
$job_id,
trim( sanitize_text_field( $file ) ),
trim( sanitize_text_field( $file_local ) )
);
}
/**
* Downloads the file by chunks.
*
* @throws DecryptException When an encrypted archive needs a decryption key.
*
* @return bool True on success, false on error.
*/
public function download_by_chunks() {
$this->ensure_user_can_download();
$source_file_path = $this->data->source_file_path();
$local_file_path = $this->data->local_file_path();
$size = $this->destination->calculate_size();
$start_byte = 0;
$chunk_size = 2 * 1024 * 1024;
$end_byte = $start_byte + $chunk_size - 1;
if ( $end_byte >= $size ) {
$end_byte = $size - 1;
}
try {
while ( $end_byte <= $size ) {
$this->destination->download_chunk( $start_byte, $end_byte );
self::send_message(
[
'state' => self::STATE_DOWNLOADING,
'start_byte' => $start_byte,
'end_byte' => $end_byte,
'size' => $size,
'download_percent' => round( ( $end_byte + 1 ) / $size * 100 ),
'filename' => basename( $source_file_path ),
]
);
if ( $end_byte === $size - 1 ) {
break;
}
$start_byte = $end_byte + 1;
$end_byte = $start_byte + $chunk_size - 1;
if ( $start_byte < $size && $end_byte >= $size ) {
$end_byte = $size - 1;
}
}
if ( BackWPup::is_pro() ) {
/**
* Decryption service.
*
* @var \Inpsyde\Restore\Api\Module\Decryption\Decrypter $decrypter
*/
$decrypter = restore_container( 'decrypter' );
if ( $decrypter->isEncrypted( $local_file_path ) ) {
throw new DecryptException( DecryptController::STATE_NEED_DECRYPTION_KEY );
}
}
} catch ( Exception $e ) {
self::send_message(
[
'state' => self::STATE_ERROR,
'message' => $e->getMessage(),
],
'log'
);
return false;
}
self::send_message(
[
'state' => self::STATE_DONE,
'message' => esc_html__( 'Your download is being generated …', 'backwpup' ),
]
);
return true;
}
/**
* Downloads a file in chunks using WP-CLI.
*
* The method calculates the file size, divides it into chunks, and downloads each chunk
* sequentially until the entire file is downloaded.
*
* @return void
*/
public function download_by_chunks_wp_cli() {
$size = $this->destination->calculate_size();
$start_byte = 0;
$chunk_size = 2 * 1024 * 1024;
$end_byte = $start_byte + $chunk_size - 1;
if ( $end_byte >= $size ) {
$end_byte = $size - 1;
}
/* translators: %s: file name */
$progress = \WP_CLI\Utils\make_progress_bar( sprintf( __( 'Download %s:', 'backwpup' ), basename( $this->data->source_file_path() ) ), $size );
try {
while ( $end_byte <= $size ) {
$this->destination->download_chunk( $start_byte, $end_byte );
$progress->tick( $chunk_size );
if ( $end_byte === $size - 1 ) {
$progress->finish();
break;
}
$start_byte = $end_byte + 1;
$end_byte = $start_byte + $chunk_size - 1;
if ( $start_byte < $size && $end_byte >= $size ) {
$end_byte = $size - 1;
}
}
} catch ( \Exception $e ) {
/* translators: %s: error message */
\WP_CLI::error( sprintf( __( 'Backup file download error: %s.', 'backwpup' ), $e->getMessage() ) );
}
}
/**
* Ensure user capability.
*
* @return void
*/
private function ensure_user_can_download() {
if ( ! current_user_can( self::CAPABILITY ) ) {
wp_die();
}
}
/**
* Send event source message.
*
* @param array $data Message data.
* @param string $event Event name.
*
* @return void
*/
private static function send_message( $data, $event = 'message' ) {
echo 'event: ' . esc_html( $event ) . "\n";
echo 'data: ' . wp_json_encode( $data ) . "\n\n";
flush();
}
}