path("exports"); if (!is_dir($exportDir)) { mkdir($exportDir, 0755, true); } $stamp = now()->format("Y_m_d_His"); $sqlFile = $exportDir . "/dump_{$stamp}.sql"; $zipFile = $exportDir . "/export_{$stamp}.zip"; $publicDisk = Storage::disk("public"); $filesDir = $publicDisk->path(""); $result = $this->dumpDatabase($db, $sqlFile)->flatMap( fn($sql) => $this->buildZip($sql, $filesDir, $zipFile), ); if (file_exists($sqlFile)) { unlink($sqlFile); } if ($result->error()->isDefined()) { $this->error($result->error()->get()); return; } $this->info("Exported to {$zipFile}"); } /** @return Result */ private function dumpDatabase(array $db, string $sqlFile): Result { $command = sprintf( "PGPASSWORD=%s pg_dump -h %s -p %s -U %s -d %s --no-owner --no-acl > %s", $db["password"], $db["host"], $db["port"], $db["username"], $db["database"], $sqlFile, ); exec($command, result_code: $code); if ($code !== 0) { return Error::create("pg_dump failed."); } $this->info("Database dumped."); return Success::create($sqlFile); } /** @return Result */ private function buildZip( string $sqlFile, string $filesDir, string $zipFile, ): Result { $zip = new ZipArchive(); if ( $zip->open($zipFile, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== true ) { return Error::create("Could not create zip archive."); } $zip->addFile($sqlFile, basename($sqlFile)); if (is_dir($filesDir)) { $iterator = new \RecursiveIteratorIterator( new \RecursiveDirectoryIterator( $filesDir, \FilesystemIterator::SKIP_DOTS, ), ); foreach ($iterator as $file) { $relativePath = "files/" . ltrim( str_replace($filesDir, "", $file->getRealPath()), DIRECTORY_SEPARATOR, ); $zip->addFile($file->getRealPath(), $relativePath); } } $zip->close(); return Success::create($zipFile); } }