backend-01

commit 262fe3a98dc7b04b3e331a95bfae542a27298a87

Author: Pedro Lucas Porcellis <porcellis@eletrotupi.com>

bill: isolate file uploading logic into its own service

 app/controllers/BillsController.php | 16 ++++----
 app/services/FileUploadingService.php | 50 +++++++++++++++++++++++++++++


diff --git a/app/controllers/BillsController.php b/app/controllers/BillsController.php
index 9d5063f6277c3e65772c0d33e39b975ed50160a3..910092015afd2517858f3abe275c770b03f82bc9 100644
--- a/app/controllers/BillsController.php
+++ b/app/controllers/BillsController.php
@@ -3,6 +3,7 @@
 require_once __DIR__ . '/../daos/BillDAO.php';
 require_once __DIR__ . '/../daos/TagDAO.php';
 require_once __DIR__ . '/../models/Bill.php';
+require_once __DIR__ . '/../services/FileUploadingService.php';
 
 class BillsController {
   private $billDAO;
@@ -36,15 +37,14 @@   public function store() {
     $data = $_POST;
 
     $pdfPath = null;
-    if (isset($_FILES['pdf']) && $_FILES['pdf']['error'] === UPLOAD_ERR_OK) {
-      $uploadDir = '../storage/uploads/';
-      $fileName = uniqid() . '_' . basename($_FILES['pdf']['name']);
-      $pdfPath = $uploadDir . $fileName;
+    $fileUploadingService = new FileUploadingService();
+    $uploadResult = $fileUploadingService->upload($_FILES['pdf'], 'bill_');
 
-      if (!move_uploaded_file($_FILES['pdf']['tmp_name'], $pdfPath)) {
-        echo "Failed to upload PDF.";
-        return;
-      }
+    if ($uploadResult['success']) {
+      $pdfPath = $uploadResult['filePath'];
+    } elseif (isset($uploadResult['error'])) {
+      echo 'Error: ' . $uploadResult['error'];
+      return;
     }
 
     $bill = new Bill(




diff --git a/app/services/FileUploadingService.php b/app/services/FileUploadingService.php
new file mode 100644
index 0000000000000000000000000000000000000000..44c84c231a355da5151a0b9920cf78986959c333
--- /dev/null
+++ b/app/services/FileUploadingService.php
@@ -0,0 +1,50 @@
+<?php
+
+class FileUploadingService {
+  const UPLOAD_DIR = __DIR__ . '/../../storage/uploads/';
+  private $uploadDir;
+
+  public function __construct() {
+    $this->uploadDir = self::UPLOAD_DIR;
+
+    if (!is_dir($this->uploadDir)) {
+      mkdir($this->uploadDir, 0755, true);
+    }
+  }
+
+  public function upload($file, $prefix = 'pdf_') {
+    if (!isset($file) || $file['error'] !== UPLOAD_ERR_OK) {
+      return [
+        'success' => false,
+        'error' => $this->getUploadErrorMessage($file['error'] ?? UPLOAD_ERR_NO_FILE)
+      ];
+    }
+
+    $fileName = $this->generateUniqueFileName(
+      $prefix,
+      pathinfo($file['name'], PATHINFO_EXTENSION)
+    );
+
+    $filePath = $this->uploadDir . $fileName;
+
+    if (move_uploaded_file($file['tmp_name'], $filePath)) {
+      return ['success' => true, 'filePath' => 'storage/uploads/' . $fileName];
+    }
+
+    return ['success' => false, 'error' => 'Failed to move the uploaded file.'];
+  }
+
+  private function generateUniqueFileName($prefix, $extension) {
+    return uniqid($prefix, true) . '.' . $extension;
+  }
+
+  private function getUploadErrorMessage($errorCode) {
+    // TODO: Map other errors?
+    $errors = [
+      UPLOAD_ERR_NO_FILE    => 'No file was uploaded.',
+      UPLOAD_ERR_CANT_WRITE => 'Failed to write file to disk.'
+    ];
+
+    return $errors[$errorCode] ?? 'Unknown error during file upload.';
+  }
+}