file = $file; $this->config = $config; $this->uploadDir = rtrim($config['uploads']['tmp_path'], '/') . '/'; $this->uuid = uniqid(); $this->fileExt = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION)); } public function validate(): bool { if ($this->file['error'] !== UPLOAD_ERR_OK) { $this->errors[] = "File upload error."; } if ($this->file['size'] > $this->config['uploads']['max_file_size']) { $this->errors[] = "File is too large."; } if (!in_array($this->fileExt, $this->config['uploads']['allowed_file_types'])) { $this->errors[] = "File type not allowed."; } if (!in_array($this->file['type'], $this->config['uploads']['allowed_mime_type'])) { $this->errors[] = "MIME type not allowed."; } return empty($this->errors); } public function getErrors(): array { return $this->errors; } public function moveFile(): bool { $destination = $this->uploadDir . $this->uuid . "." . $this->fileExt; if (move_uploaded_file($this->file['tmp_name'], $destination)) { $this->localPath = $destination; return true; } $this->errors[] = "Failed to move uploaded file."; return false; } public function process(): array { // Assuming moveFile() has been called $uploadTask = [ 'original_name' => $this->file['name'], 'local_path' => $this->localPath, 'size' => $this->file['size'], 'ext' => $this->fileExt, ]; if ($this->fileExt === "mp3") { $escapedFile = escapeshellarg($this->localPath); $artist = trim(shell_exec("eyed3 --query='%a%' $escapedFile")); $title = trim(shell_exec("eyed3 --query='%t%' $escapedFile")); $duration = trim(shell_exec("mp3info -p \"%S\" $escapedFile")); $uploadTask['file_type'] = 'mp3'; $uploadTask['metadata'] = [ 'artist' => $artist, 'title' => $title, 'duration' => $duration, ]; $uploadTask['mediaplayer'] = 0; } elseif ($this->fileExt === "zip") { $zip = new \ZipArchive; if ($zip->open($this->localPath) === true) { $totalDuration = 0; $tracklist = []; for ($i = 0; $i < $zip->numFiles; $i++) { $entryName = $zip->getNameIndex($i); $entryExt = strtolower(pathinfo($entryName, PATHINFO_EXTENSION)); if ($entryExt === "mp3") { $tempDir = $this->uploadDir . uniqid('zip_'); mkdir($tempDir); $tempFilePath = $tempDir . '/' . basename($entryName); $zip->extractTo($tempDir, $entryName); $escapedFile = escapeshellarg($tempFilePath); $title = trim(shell_exec("eyed3 --query='%t%' $escapedFile")); $duration = trim(shell_exec("mp3info -p \"%S\" $escapedFile")); $tracklist[] = $title ?: basename($entryName); $totalDuration += (int)$duration; unlink($tempFilePath); rmdir($tempDir); } } $zip->close(); $uploadTask['file_type'] = 'zip'; $uploadTask['metadata'] = [ 'tracklist' => $tracklist, 'total_duration' => $totalDuration, ]; $uploadTask['mediaplayer'] = 1; } else { $this->errors[] = "Failed to open ZIP file."; } } else { $this->errors[] = "Unsupported file type."; } return $uploadTask; } public function uploadToCDN(CDN $cdn): string { // Create a remote path – e.g., under a temp folder with a unique name $remotePath = "temp/mixes/" . uniqid() . "_" . basename($this->localPath); $mimeType = ($this->fileExt === 'mp3') ? 'audio/mpeg' : 'application/zip'; $cdn->uploadFile($this->localPath, $remotePath, $mimeType); return $remotePath; } }