requestData = $requestData; $this->userId = $userId; $this->jobId = $jobId; } public function handle(): void { try { // Etapa 1: Inicio (0%) $this->broadcastProgress(0, 'processing', 'Iniciando validación de archivos...'); // Procesar archivos $result = $this->processFiles(); // Etapa final: Completado (100%) $this->broadcastProgress(100, 'completed', 'Archivos subidos exitosamente', $result); } catch (\Exception $e) { $this->broadcastProgress(0, 'failed', 'Error en la validación: ' . $e->getMessage()); } } private function processFiles() { if (!isset($this->requestData['temp_files'])) { throw new \Exception('temp_files not found in request data'); } $tempFiles = $this->requestData['temp_files']; if (!isset($tempFiles['zip'])) { throw new \Exception('ZIP file not found in temp_files'); } $this->broadcastProgress(50, 'processing', 'Extrayendo y subiendo archivos individuales...'); $individualFiles = $this->extractAndUploadIndividualFiles($tempFiles['zip']); return [ 'temp_files' => $tempFiles, 'individual_temp_files' => $individualFiles ]; } private function broadcastProgress($progress, $status, $message, $data = null) { $progressData = [ 'progress' => $progress, 'status' => $status, 'message' => $message, 'data' => $data, 'jobId' => $this->jobId ]; $webSocketService = new WebSocketService(); $webSocketService->emitToUser($this->userId, 'file_validation_progress', $progressData); } private function extractAndUploadIndividualFiles($zipTempId) { try { // Get ZIP file from temp storage using DocumentManagementController $encryptionController = new EncryptionController(); $tempIdDec = $encryptionController->decrypt($zipTempId); if (!$tempIdDec) { return []; } $tempFile = DB::table('S002V01TARTE')->where('ARTE_IDAR', $tempIdDec)->first(); if (!$tempFile) { return []; } $zipPath = $tempFile->ARTE_UBTE; if (!file_exists($zipPath)) { return []; } $zip = new ZipArchive(); if ($zip->open($zipPath) !== TRUE) { return []; } $tempFiles = []; $tempDir = storage_path('app/temp_extracted_' . time()); mkdir($tempDir, 0755, true); for ($i = 0; $i < $zip->numFiles; $i++) { $fullPath = $zip->getNameIndex($i); // Skip directories if (substr($fullPath, -1) === '/') continue; $fileName = basename($fullPath); if (empty($fileName)) continue; $fileContent = $zip->getFromIndex($i); if ($fileContent !== false) { $extractPath = $tempDir . '/' . $fileName; if (file_put_contents($extractPath, $fileContent)) { $tempFileId = $this->uploadExtractedFileToTemp($extractPath, $fileName); if ($tempFileId) { $tempFiles[] = [ 'original_name' => $fileName, 'temp_id' => $tempFileId ]; } unlink($extractPath); } } } $zip->close(); $this->removeDirectory($tempDir); return $tempFiles; } catch (\Exception $e) { return []; } } private function uploadExtractedFileToTemp($filePath, $fileName) { try { $extension = strtolower(pathinfo($fileName, PATHINFO_EXTENSION)); $mimeType = $this->getMimeType($extension); $uploadedFile = new UploadedFile( $filePath, $fileName, $mimeType, null, true ); $encryptionController = new EncryptionController(); $request = new Request(); $request->files->set('file', $uploadedFile); $request->merge([ 'id_user' => $encryptionController->encrypt($this->requestData['id_user']), 'linea' => $this->requestData['linea'] ]); $documentController = new DocumentManagementController(); $response = $documentController->uploadTempFile($request); $data = json_decode($response->getContent()); return $data->error ? false : $data->response->idArchivo; } catch (\Exception $e) { return false; } } private function getMimeType($extension) { $mimeTypes = [ 'pdf' => 'application/pdf', 'doc' => 'application/msword', 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'xls' => 'application/vnd.ms-excel', 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'ppt' => 'application/vnd.ms-powerpoint', 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', 'jpg' => 'image/jpeg', 'jpeg' => 'image/jpeg', 'png' => 'image/png', 'gif' => 'image/gif', 'bmp' => 'image/bmp', 'txt' => 'text/plain', 'dwg' => 'application/acad', 'dxf' => 'application/dxf' ]; return $mimeTypes[$extension] ?? 'application/octet-stream'; } private function removeDirectory($dir) { if (!is_dir($dir)) return; $files = array_diff(scandir($dir), ['.', '..']); foreach ($files as $file) { $path = $dir . '/' . $file; is_dir($path) ? $this->removeDirectory($path) : unlink($path); } rmdir($dir); } }