diff --git a/app/Config/Routes.php b/app/Config/Routes.php index 5876aab..af914b5 100644 --- a/app/Config/Routes.php +++ b/app/Config/Routes.php @@ -156,7 +156,7 @@ $routes->get('/activities/suspend/(:num)', 'Activities::suspend/$1'); $routes->get('/activities/disable/(:num)', 'Activities::disable/$1'); // $routes->get('/activities/delete/(:num)', 'Activities::delete/$1'); $routes->match(['get','post'],'/activities/save', 'Activities::save'); -$routes->post('/activities/upload', 'Activities::upload'); +$routes->match(['post', 'options'], '/activities/upload', 'Activities::upload'); $routes->get('/activities/getproduct/(:num)', 'Activities::getproduct/$1/$2/$3'); $routes->get('/activities/getvendor/(:num)', 'Activities::getvendor/$1'); $routes->get('/activities/getconsumable/(:num)', 'Activities::getconsumable/$1'); @@ -335,4 +335,4 @@ $routes->get('/api/getProductSites', 'Api::getProductSites'); */ // if (is_file(APPPATH . 'Config/' . ENVIRONMENT . '/Routes.php')) { // require APPPATH . 'Config/' . ENVIRONMENT . '/Routes.php'; -// } \ No newline at end of file +// } diff --git a/app/Controllers/Activities.php b/app/Controllers/Activities.php index 4efb724..ce67973 100644 --- a/app/Controllers/Activities.php +++ b/app/Controllers/Activities.php @@ -9,6 +9,7 @@ use App\Models\ActdetailModel; use App\Models\InvTransModel; use CodeIgniter\Controller; +use CodeIgniter\HTTP\Files\UploadedFile; class Activities extends Controller { @@ -98,6 +99,28 @@ class Activities extends Controller { return implode(',', array_unique(array_filter($normalized))); } + + protected function findFirstUploadedFile(array $files): ?UploadedFile + { + foreach ($files as $file) { + if ($file instanceof UploadedFile) { + if ($file->getError() !== UPLOAD_ERR_NO_FILE) { + return $file; + } + + continue; + } + + if (is_array($file)) { + $uploadedFile = $this->findFirstUploadedFile($file); + if ($uploadedFile !== null) { + return $uploadedFile; + } + } + } + + return null; + } public function index() { $data = array(); @@ -1075,35 +1098,62 @@ class Activities extends Controller { return $datas; } - public function upload(){ - if ($this->request->getMethod() === 'POST') { - if ( 0 < $_FILES['file']['error'] ) { - return $this->response->setJSON([ - 'status' => 'error', - 'message' => 'Upload failed', - 'error' => $_FILES['file']['error'], - ]); - } - else { - $subfolder = $this->getAttachmentSubfolder(); - $uploadDir = FCPATH . "upload/$subfolder/"; - if (!is_dir($uploadDir)) { - mkdir($uploadDir, 0755, true); - } - $filename = basename(str_replace('\\', '/', $_FILES['file']['name'])); - if (!move_uploaded_file($_FILES['file']['tmp_name'], $uploadDir . $filename)) { - return $this->response->setJSON([ - 'status' => 'error', - 'message' => 'Unable to save upload', - ]); - } - return $this->response->setJSON([ - 'status' => 'success', - 'relativePath' => $this->buildAttachmentRelativePath($filename), - 'filename' => $filename, - ]); - } - } + public function upload() + { + $method = strtolower($this->request->getMethod()); + if ($method === 'options') { + return $this->response->setStatusCode(204); + } + + if ($method !== 'post') { + return $this->response->setStatusCode(405)->setJSON([ + 'status' => 'error', + 'message' => 'Invalid request method', + ]); + } + + $file = $this->request->getFile('file'); + if ($file === null || $file->getError() === UPLOAD_ERR_NO_FILE) { + $file = $this->findFirstUploadedFile($this->request->getFiles()); + } + + if ($file === null || $file->getError() === UPLOAD_ERR_NO_FILE) { + return $this->response->setStatusCode(400)->setJSON([ + 'status' => 'error', + 'message' => 'No file uploaded', + ]); + } + + if (! $file->isValid()) { + return $this->response->setStatusCode(400)->setJSON([ + 'status' => 'error', + 'message' => 'Upload failed', + 'error' => $file->getErrorString(), + ]); + } + + $subfolder = $this->getAttachmentSubfolder(); + $uploadDir = FCPATH . 'upload/' . $subfolder . '/'; + if (! is_dir($uploadDir) && ! mkdir($uploadDir, 0755, true) && ! is_dir($uploadDir)) { + return $this->response->setStatusCode(500)->setJSON([ + 'status' => 'error', + 'message' => 'Unable to create upload directory', + ]); + } + + $filename = basename(str_replace('\\', '/', $file->getClientName())); + if (! $file->move($uploadDir, $filename, true)) { + return $this->response->setStatusCode(500)->setJSON([ + 'status' => 'error', + 'message' => 'Unable to save upload', + ]); + } + + return $this->response->setJSON([ + 'status' => 'success', + 'relativePath' => $this->buildAttachmentRelativePath($filename), + 'filename' => $filename, + ]); } public function act_content($actid, $filter_email=false) { // Parameter Ke-2 Untuk Email diff --git a/app/Views/activities_editor.php b/app/Views/activities_editor.php index 7c257f4..8ebdd3f 100644 --- a/app/Views/activities_editor.php +++ b/app/Views/activities_editor.php @@ -1179,7 +1179,7 @@ toggleCalibrateAccordion(); endSection() ?> diff --git a/public/assets/uppy/uppy-old.js b/public/assets/uppy/uppy-old.js index f2cd5f7..730e776 100644 --- a/public/assets/uppy/uppy-old.js +++ b/public/assets/uppy/uppy-old.js @@ -1,6 +1,7 @@ import { Uppy, Dashboard, XHRUpload } from "https://releases.transloadit.com/uppy/v3.15.0/uppy.min.mjs"; const uploadEndpoint = window.crmActivitiesUploadEndpoint ?? "/activities/upload"; +const attachmentInput = document.querySelector("#attachment"); // var uppy = new Uppy({ // onBeforeFileAdded: (currentFile, files) => { @@ -57,7 +58,12 @@ onBeforeFileAdded: (currentFile, files) => { height: 300, }) -.use(XHRUpload, { endpoint: uploadEndpoint, method: 'post' }); +.use(XHRUpload, { + endpoint: uploadEndpoint, + method: "post", + fieldName: "file", + formData: true, +}); uppy.on("complete", (result) => { let array = result.successful; @@ -73,17 +79,45 @@ uppy.on("complete", (result) => { let text = arrtext.join(); - $('#attachment').val(function(){ - if (this.value == '') { - return this.value + text; - } else if (this.value != ''){ - return this.value + ',' + text; - } - }); + if (attachmentInput) { + $(attachmentInput).val(function(){ + if (this.value === "") { + return this.value + text; + } + + return this.value + "," + text; + }); + } console.log( "Upload complete! We’ve uploaded these files:", result.successful); }); +uppy.on("upload-error", (file, error, response) => { + const fallbackMessage = error?.message ?? "Upload failed"; + const responseMessage = response?.body?.message ?? response?.statusText ?? ""; + const fileName = file?.name ?? "file"; + const message = responseMessage !== "" ? responseMessage : fallbackMessage; + + console.error("Uppy upload-error", { + file, + error, + response, + uploadEndpoint, + }); + + alert("Upload failed for " + fileName + ": " + message); +}); + +uppy.on("restriction-failed", (file, error) => { + console.error("Uppy restriction-failed", { file, error }); + alert(error?.message ?? "File is not allowed."); +}); + +uppy.on("error", (error) => { + console.error("Uppy error", error); + alert(error?.message ?? "Unexpected uploader error."); +}); + /* const attachmentList = document.querySelector('#attachment').value; const arrayx = attachmentList ? attachmentList.split(',') : [];