96 lines
3.4 KiB
PHP
96 lines
3.4 KiB
PHP
<?php
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
use Illuminate\Console\Command;
|
|
use Illuminate\Support\Facades\Http;
|
|
use Illuminate\Support\Str;
|
|
|
|
class BackupUploadFileCommand extends Command
|
|
{
|
|
protected $signature = 'backup:upload-file
|
|
{file : Path file .backup yang akan dikirim}
|
|
{--url= : Base URL server cloud backup}
|
|
{--token= : Token API cloud backup}
|
|
{--name= : Nama backup}
|
|
{--chunk-size= : Ukuran chunk dalam byte}';
|
|
|
|
protected $description = 'Upload file backup ke duidev.com secara bertahap/chunked.';
|
|
|
|
public function handle(): int
|
|
{
|
|
$file = (string) $this->argument('file');
|
|
if (!is_file($file) || !is_readable($file)) {
|
|
$this->error('File backup tidak ditemukan atau tidak bisa dibaca: ' . $file);
|
|
return Command::FAILURE;
|
|
}
|
|
|
|
$baseUrl = rtrim((string) ($this->option('url') ?: config('cloud_backup.api_url')), '/');
|
|
$token = (string) ($this->option('token') ?: config('cloud_backup.api_token'));
|
|
$backupName = (string) ($this->option('name') ?: config('cloud_backup.backup_name', 'lismikro'));
|
|
$chunkSize = (int) ($this->option('chunk-size') ?: config('cloud_backup.chunk_size', 5 * 1024 * 1024));
|
|
|
|
if ($baseUrl === '' || $token === '') {
|
|
$this->error('CLOUD_BACKUP_API_URL dan CLOUD_BACKUP_API_TOKEN wajib diisi.');
|
|
return Command::FAILURE;
|
|
}
|
|
|
|
if ($chunkSize < 1024 * 1024) {
|
|
$this->error('Chunk size minimal 1 MB.');
|
|
return Command::FAILURE;
|
|
}
|
|
|
|
$size = filesize($file);
|
|
$checksum = hash_file('sha256', $file);
|
|
$totalChunks = (int) ceil($size / $chunkSize);
|
|
$uploadId = now()->format('YmdHis') . '_' . Str::random(16);
|
|
$endpoint = $baseUrl . '/api/backups/chunk';
|
|
|
|
$this->info('Upload backup: ' . basename($file));
|
|
$this->info('Total chunk: ' . $totalChunks);
|
|
|
|
$handle = fopen($file, 'rb');
|
|
if (!$handle) {
|
|
$this->error('Gagal membuka file backup.');
|
|
return Command::FAILURE;
|
|
}
|
|
|
|
try {
|
|
for ($index = 0; $index < $totalChunks; $index++) {
|
|
$chunk = fread($handle, $chunkSize);
|
|
if ($chunk === false) {
|
|
$this->error('Gagal membaca chunk ke-' . $index);
|
|
return Command::FAILURE;
|
|
}
|
|
|
|
$response = Http::withToken($token)
|
|
->timeout(300)
|
|
->attach('chunk', $chunk, 'chunk_' . $index . '.part')
|
|
->post($endpoint, [
|
|
'backup_name' => $backupName,
|
|
'upload_id' => $uploadId,
|
|
'filename' => basename($file),
|
|
'chunk_index' => $index,
|
|
'total_chunks' => $totalChunks,
|
|
'total_size' => $size,
|
|
'checksum' => $checksum,
|
|
]);
|
|
|
|
if (!$response->successful()) {
|
|
$this->error('Upload chunk ke-' . $index . ' gagal. HTTP ' . $response->status());
|
|
$this->line($response->body());
|
|
return Command::FAILURE;
|
|
}
|
|
|
|
$this->line('Chunk ' . ($index + 1) . '/' . $totalChunks . ' terkirim.');
|
|
}
|
|
} finally {
|
|
fclose($handle);
|
|
}
|
|
|
|
$this->info('Upload backup selesai.');
|
|
|
|
return Command::SUCCESS;
|
|
}
|
|
}
|