diff --git a/index_parentPhotoDeleteProcess.php b/index_parentPhotoDeleteProcess.php index 380c6655f8..0beff949b9 100644 --- a/index_parentPhotoDeleteProcess.php +++ b/index_parentPhotoDeleteProcess.php @@ -21,6 +21,7 @@ //Gibbon system-wide includes +use Gibbon\Contracts\Filesystem\FileHandler; use Gibbon\Http\Url; include './gibbon.php'; @@ -47,6 +48,8 @@ header("Location: {$URL->withReturn('error2')}"); } else { //UPDATE + $fileDeleted = $container->get(FileHandler::class)->deleteFile('gibbonPerson', $gibbonPersonID, 'image_240'); + try { $data = array('gibbonPersonID' => $gibbonPersonID); $sql = "UPDATE gibbonPerson SET image_240='' WHERE gibbonPersonID=:gibbonPersonID"; diff --git a/modules/Activities/activities_categories_deleteProcess.php b/modules/Activities/activities_categories_deleteProcess.php index 110d59c6d3..43cf84356d 100755 --- a/modules/Activities/activities_categories_deleteProcess.php +++ b/modules/Activities/activities_categories_deleteProcess.php @@ -17,6 +17,7 @@ along with this program. If not, see . */ +use Gibbon\Contracts\Filesystem\FileHandler; use Gibbon\Data\Validator; use Gibbon\Domain\Activities\ActivityCategoryGateway; @@ -51,6 +52,10 @@ $deleted = $categoryGateway->delete($gibbonActivityCategoryID); + if ($deleted) { + $fileDeleted = $container->get(FileHandler::class)->deleteFile('gibbonActivityCategory', $gibbonActivityCategoryID, 'backgroundImage'); + } + $URL .= !$deleted ? '&return=error2' : '&return=success0'; diff --git a/modules/Activities/activities_manage_deleteProcess.php b/modules/Activities/activities_manage_deleteProcess.php index 183137321e..6eda7df842 100644 --- a/modules/Activities/activities_manage_deleteProcess.php +++ b/modules/Activities/activities_manage_deleteProcess.php @@ -19,6 +19,9 @@ along with this program. If not, see . */ +use Gibbon\Contracts\Filesystem\FileHandler; +use Gibbon\Domain\Activities\ActivityPhotoGateway; + include '../../gibbon.php'; $gibbonActivityID = $_POST['gibbonActivityID'] ?? ''; @@ -50,6 +53,13 @@ $URL .= '&return=error2'; header("Location: {$URL}"); } else { + // Delete file attachments for all activity photos before deleting the activity + $activityPhotos = $container->get(ActivityPhotoGateway::class)->selectBy(['gibbonActivityID' => $gibbonActivityID], ['gibbonActivityPhotoID'])->fetchAll(); + + foreach ($activityPhotos as $photo) { + $photoDeleted = $container->get(FileHandler::class)->deleteFile('gibbonActivityPhoto', $photo['gibbonActivityPhotoID'], 'filePath'); + } + //Write to database try { $data = array('gibbonActivityID' => $gibbonActivityID); diff --git a/modules/Data Updater/data_medical_manage_deleteProcess.php b/modules/Data Updater/data_medical_manage_deleteProcess.php index 77c15bcb48..5c8672e5b9 100644 --- a/modules/Data Updater/data_medical_manage_deleteProcess.php +++ b/modules/Data Updater/data_medical_manage_deleteProcess.php @@ -19,6 +19,9 @@ along with this program. If not, see . */ +use Gibbon\Contracts\Filesystem\FileHandler; +use Gibbon\Domain\DataUpdater\MedicalConditionUpdateGateway; + include '../../gibbon.php'; $gibbonSchoolYearID = $_POST['gibbonSchoolYearID'] ?? $session->get('gibbonSchoolYearID'); @@ -51,6 +54,9 @@ $URL .= '&return=error2'; header("Location: {$URL}"); } else { + // Fetch child condition update IDs before deleting the parent record + $conditionUpdates = $container->get(MedicalConditionUpdateGateway::class)->selectBy(['gibbonPersonMedicalUpdateID' => $gibbonPersonMedicalUpdateID], ['gibbonPersonMedicalConditionUpdateID'])->fetchAll(); + //Write to database try { $data = array('gibbonPersonMedicalUpdateID' => $gibbonPersonMedicalUpdateID); @@ -62,6 +68,11 @@ header("Location: {$URL}"); exit(); } + + // Delete file attachments for all condition updates linked to this medical update + foreach ($conditionUpdates as $conditionUpdate) { + $fileDeleted = $container->get(FileHandler::class)->deleteFile('gibbonPersonMedicalConditionUpdate', $conditionUpdate['gibbonPersonMedicalConditionUpdateID'], 'attachment'); + } $URLDelete = $URLDelete.'&return=success0'; header("Location: {$URLDelete}"); diff --git a/modules/Departments/department_edit_resource_deleteProcess.php b/modules/Departments/department_edit_resource_deleteProcess.php index 675648820f..99f44d65ff 100644 --- a/modules/Departments/department_edit_resource_deleteProcess.php +++ b/modules/Departments/department_edit_resource_deleteProcess.php @@ -19,6 +19,7 @@ along with this program. If not, see . */ +use Gibbon\Contracts\Filesystem\FileHandler; use Gibbon\Domain\Departments\DepartmentResourceGateway; include '../../gibbon.php'; @@ -73,6 +74,8 @@ exit(); } + $fileDeleted = $container->get(FileHandler::class)->deleteFile('gibbonDepartmentResource', $gibbonDepartmentResourceID, 'url'); + $URL .= '&return=success0'; header("Location: {$URL}"); } diff --git a/modules/Formal Assessment/externalAssessment_manage_details_deleteProcess.php b/modules/Formal Assessment/externalAssessment_manage_details_deleteProcess.php index dfe5bd5c0b..1bbfc4b64d 100644 --- a/modules/Formal Assessment/externalAssessment_manage_details_deleteProcess.php +++ b/modules/Formal Assessment/externalAssessment_manage_details_deleteProcess.php @@ -1,6 +1,4 @@ . */ +use Gibbon\Contracts\Filesystem\FileHandler; +use Gibbon\Domain\FormalAssessment\ExternalAssessmentStudentGateway; + include '../../gibbon.php'; $gibbonExternalAssessmentStudentID = $_POST['gibbonExternalAssessmentStudentID'] ?? ''; @@ -80,6 +81,8 @@ exit(); } + $fileDeleted = $container->get(FileHandler::class)->deleteFile('gibbonExternalAssessmentStudent', $gibbonExternalAssessmentStudentID, 'attachment'); + $URLDelete = $URLDelete.'&return=success0'; header("Location: {$URLDelete}"); } diff --git a/modules/Formal Assessment/internalAssessment_manage_deleteProcess.php b/modules/Formal Assessment/internalAssessment_manage_deleteProcess.php index f8389014c4..b4134a8dbb 100644 --- a/modules/Formal Assessment/internalAssessment_manage_deleteProcess.php +++ b/modules/Formal Assessment/internalAssessment_manage_deleteProcess.php @@ -19,6 +19,7 @@ along with this program. If not, see . */ +use Gibbon\Contracts\Filesystem\FileHandler; use Gibbon\Domain\FormalAssessment\InternalAssessmentColumnGateway; include '../../gibbon.php'; @@ -57,6 +58,8 @@ exit(); } + $fileDeleted = $container->get(FileHandler::class)->deleteFile('gibbonInternalAssessmentColumn', $gibbonInternalAssessmentColumnID, 'attachment'); + $URLDelete = $URLDelete.'&return=success0'; header("Location: {$URLDelete}"); } diff --git a/modules/Formal Assessment/internalAssessment_write_data_responseDeleteProcess.php b/modules/Formal Assessment/internalAssessment_write_data_responseDeleteProcess.php index e817ab126d..fbe3bebca9 100644 --- a/modules/Formal Assessment/internalAssessment_write_data_responseDeleteProcess.php +++ b/modules/Formal Assessment/internalAssessment_write_data_responseDeleteProcess.php @@ -20,6 +20,8 @@ */ use Gibbon\Data\Validator; +use Gibbon\Domain\FormalAssessment\InternalAssessmentEntryGateway; +use Gibbon\Contracts\Filesystem\FileHandler; require_once '../../gibbon.php'; @@ -55,6 +57,13 @@ } $URL .= '&return=success0'; + + $entryRow = $container->get(InternalAssessmentEntryGateway::class)->selectBy(['gibbonPersonIDStudent' => $gibbonPersonID, 'gibbonInternalAssessmentColumnID' => $gibbonInternalAssessmentColumnID], ['gibbonInternalAssessmentEntryID'])->fetch(); + + if (!empty($entryRow)) { + $fileDeleted = $container->get(FileHandler::class)->deleteFile('gibbonInternalAssessmentEntry', $entryRow['gibbonInternalAssessmentEntryID'], 'response'); + } + //Success 0 header("Location: {$URL}"); } diff --git a/modules/Library/library_manage_catalog_deleteProcess.php b/modules/Library/library_manage_catalog_deleteProcess.php index d3a4d3b09e..48cf28ea8b 100644 --- a/modules/Library/library_manage_catalog_deleteProcess.php +++ b/modules/Library/library_manage_catalog_deleteProcess.php @@ -19,6 +19,8 @@ along with this program. If not, see . */ +use Gibbon\Contracts\Filesystem\FileHandler; + include '../../gibbon.php'; include './moduleFunctions.php'; @@ -57,6 +59,8 @@ } //Success 0 + $fileDeleted = $container->get(FileHandler::class)->deleteFile('gibbonLibraryItem', $queryArr['gibbonLibraryItemID'], 'imageLocation'); + $queryArr['q'] = "/modules/".getModuleName($_POST['address'])."/library_manage_catalog.php"; $queryArr['return'] = "success0"; header("Location: " . $baseURL . http_build_query($queryArr)); diff --git a/modules/Markbook/markbook_edit_data_responseDeleteProcess.php b/modules/Markbook/markbook_edit_data_responseDeleteProcess.php index ea74e906ce..96267ff480 100644 --- a/modules/Markbook/markbook_edit_data_responseDeleteProcess.php +++ b/modules/Markbook/markbook_edit_data_responseDeleteProcess.php @@ -19,7 +19,9 @@ along with this program. If not, see . */ +use Gibbon\Contracts\Filesystem\FileHandler; use Gibbon\Data\Validator; +use Gibbon\Domain\Markbook\MarkbookEntryGateway; require_once '../../gibbon.php'; @@ -55,6 +57,14 @@ } $URL .= '&return=success0'; + + // Delete the file attachment for this entry response + $entryRow = $container->get(MarkbookEntryGateway::class)->selectBy(['gibbonPersonIDStudent' => $gibbonPersonID, 'gibbonMarkbookColumnID' => $gibbonMarkbookColumnID], ['gibbonMarkbookEntryID'])->fetch(); + + if (!empty($entryRow)) { + $fileDeleted = $container->get(FileHandler::class)->deleteFile('gibbonMarkbookEntry', $entryRow['gibbonMarkbookEntryID'], 'response'); + } + //Success 0 header("Location: {$URL}"); } diff --git a/modules/Markbook/markbook_edit_deleteProcess.php b/modules/Markbook/markbook_edit_deleteProcess.php index 33398420df..1afa0c15b7 100644 --- a/modules/Markbook/markbook_edit_deleteProcess.php +++ b/modules/Markbook/markbook_edit_deleteProcess.php @@ -19,6 +19,9 @@ along with this program. If not, see . */ +use Gibbon\Contracts\Filesystem\FileHandler; +use Gibbon\Domain\Markbook\MarkbookEntryGateway; + include '../../gibbon.php'; $gibbonCourseClassID = $_POST['gibbonCourseClassID'] ?? ''; @@ -64,6 +67,15 @@ exit(); } + // Delete file attachments for all markbook entry responses for this column + $entryRows = $container->get(MarkbookEntryGateway::class)->selectBy(['gibbonMarkbookColumnID' => $gibbonMarkbookColumnID], ['gibbonMarkbookEntryID'])->fetchAll(); + + foreach ($entryRows as $entryRow) { + $entryFileDeleted = $container->get(FileHandler::class)->deleteFile('gibbonMarkbookEntry', $entryRow['gibbonMarkbookEntryID'], 'response'); + } + + $columnFileDeleted = $container->get(FileHandler::class)->deleteFile('gibbonMarkbookColumn', $gibbonMarkbookColumnID, 'attachment'); + $URLDelete = $URLDelete.'&return=success0'; header("Location: {$URLDelete}"); } diff --git a/modules/Planner/planner_deleteProcess.php b/modules/Planner/planner_deleteProcess.php index 5e91bd1ced..ee3bf5ddae 100644 --- a/modules/Planner/planner_deleteProcess.php +++ b/modules/Planner/planner_deleteProcess.php @@ -19,6 +19,9 @@ along with this program. If not, see . */ +use Gibbon\Contracts\Filesystem\FileHandler; +use Gibbon\Domain\Planner\PlannerEntryHomeworkGateway; + include '../../gibbon.php'; $gibbonPlannerEntryID = $_POST['gibbonPlannerEntryID'] ?? ''; @@ -85,7 +88,15 @@ $URL .= "&return=error2$params"; header("Location: {$URL}"); } else { - //Write to database + //Write to database + + // Delete file attachments for all homework entries before deleting the planner entry + $homeworkRows = $container->get(PlannerEntryHomeworkGateway::class)->selectBy(['gibbonPlannerEntryID' => $gibbonPlannerEntryID], ['gibbonPlannerEntryHomeworkID'])->fetchAll(); + + foreach ($homeworkRows as $homework) { + $homeWorkFileDeleted = $container->get(FileHandler::class)->deleteFile('gibbonPlannerEntryHomework', $homework['gibbonPlannerEntryHomeworkID'], 'location'); + } + try { $data = array('gibbonPlannerEntryID' => $gibbonPlannerEntryID); $sql = 'DELETE FROM gibbonPlannerEntryOutcome WHERE gibbonPlannerEntryID=:gibbonPlannerEntryID'; diff --git a/modules/Planner/planner_view_full_submit_deleteProcess.php b/modules/Planner/planner_view_full_submit_deleteProcess.php index a29f9b89b4..b1190fa73f 100644 --- a/modules/Planner/planner_view_full_submit_deleteProcess.php +++ b/modules/Planner/planner_view_full_submit_deleteProcess.php @@ -19,6 +19,8 @@ along with this program. If not, see . */ +use Gibbon\Contracts\Filesystem\FileHandler; + //Gibbon system-wide includes include '../../gibbon.php'; @@ -71,6 +73,8 @@ exit(); } + $fileDeleted = $container->get(FileHandler::class)->deleteFile('gibbonPlannerEntryHomework', $gibbonPlannerEntryHomeworkID, 'location'); + $URL .= '&return=success0'; header("Location: {$URL}"); } diff --git a/modules/Planner/planner_view_full_submit_studentDeleteProcess.php b/modules/Planner/planner_view_full_submit_studentDeleteProcess.php index 69b4f8a957..84e724b748 100644 --- a/modules/Planner/planner_view_full_submit_studentDeleteProcess.php +++ b/modules/Planner/planner_view_full_submit_studentDeleteProcess.php @@ -19,6 +19,7 @@ along with this program. If not, see . */ +use Gibbon\Contracts\Filesystem\FileHandler; use Gibbon\Data\Validator; require_once '../../gibbon.php'; @@ -74,6 +75,8 @@ exit(); } + $fileDeleted = $container->get(FileHandler::class)->deleteFile('gibbonPlannerEntryHomework', $gibbonPlannerEntryHomeworkID, 'location'); + $URL .= '&return=success0'; header("Location: {$URL}"); } diff --git a/modules/Planner/units_deleteProcess.php b/modules/Planner/units_deleteProcess.php index 7e5465a024..4da4f92e0c 100644 --- a/modules/Planner/units_deleteProcess.php +++ b/modules/Planner/units_deleteProcess.php @@ -19,6 +19,7 @@ along with this program. If not, see . */ +use Gibbon\Contracts\Filesystem\FileHandler; use Gibbon\Domain\Timetable\CourseGateway; include '../../gibbon.php'; @@ -111,6 +112,8 @@ header("Location: {$URL}"); exit(); } + + $fileDeleted = $container->get(FileHandler::class)->deleteFile('gibbonUnit', $gibbonUnitID, 'attachment'); $URLDelete = $URLDelete.'&return=success0'; header("Location: {$URLDelete}"); diff --git a/modules/Reports/archive_manage_deleteProcess.php b/modules/Reports/archive_manage_deleteProcess.php index ff05c66c02..5531029d91 100644 --- a/modules/Reports/archive_manage_deleteProcess.php +++ b/modules/Reports/archive_manage_deleteProcess.php @@ -19,7 +19,9 @@ along with this program. If not, see . */ +use Gibbon\Contracts\Filesystem\FileHandler; use Gibbon\Module\Reports\Domain\ReportArchiveGateway; +use Gibbon\Module\Reports\Domain\ReportArchiveEntryGateway; require_once '../../gibbon.php'; @@ -48,6 +50,13 @@ exit; } + // Delete file attachments for all entries in this archive before deleting the archive + $archiveEntries = $container->get(ReportArchiveEntryGateway::class)->selectBy(['gibbonReportArchiveID' => $gibbonReportArchiveID], ['gibbonReportArchiveEntryID'])->fetchAll(); + + foreach ($archiveEntries as $entry) { + $fileDeleted = $container->get(FileHandler::class)->deleteFile('gibbonReportArchiveEntry', $entry['gibbonReportArchiveEntryID'], 'filePath'); + } + $deleted = $reportArchiveGateway->delete($gibbonReportArchiveID); $partialFail &= !$deleted; diff --git a/modules/Reports/templates_manage_section_deleteProcess.php b/modules/Reports/templates_manage_section_deleteProcess.php index 65e3c97a8c..1d63f0cde9 100644 --- a/modules/Reports/templates_manage_section_deleteProcess.php +++ b/modules/Reports/templates_manage_section_deleteProcess.php @@ -19,6 +19,8 @@ along with this program. If not, see . */ +use Gibbon\Contracts\Filesystem\FileHandler; +use Gibbon\Domain\System\FilePointerGateway; use Gibbon\Module\Reports\Domain\ReportTemplateGateway; use Gibbon\Module\Reports\Domain\ReportTemplateSectionGateway; @@ -53,6 +55,13 @@ exit; } + // Delete any file attachments associated with this section (dynamic config columns) + $pointers = $container->get(FilePointerGateway::class)->selectBy(['foreignTable' => 'gibbonReportTemplateSection', 'foreignTableID' => $gibbonReportTemplateSectionID])->fetchAll(); + + foreach ($pointers as $pointer) { + $fileDeleted = $container->get(FileHandler::class)->deleteFile($pointer['foreignTable'], $pointer['foreignTableID'], $pointer['foreignColumn']); + } + $deleted = $templateSectionGateway->delete($gibbonReportTemplateSectionID); $URL .= !$deleted diff --git a/modules/School Admin/department_manage_deleteProcess.php b/modules/School Admin/department_manage_deleteProcess.php index bbc052e2a0..1a24e4c9a6 100644 --- a/modules/School Admin/department_manage_deleteProcess.php +++ b/modules/School Admin/department_manage_deleteProcess.php @@ -19,6 +19,9 @@ along with this program. If not, see . */ +use Gibbon\Contracts\Filesystem\FileHandler; +use Gibbon\Domain\Departments\DepartmentResourceGateway; + include '../../gibbon.php'; $gibbonDepartmentID = $_POST['gibbonDepartmentID'] ?? ''; @@ -72,6 +75,19 @@ exit(); } + // Delete related department resources and files + $fileHandler = $container->get(FileHandler::class); + $departmentResourceGateway = $container->get(DepartmentResourceGateway::class); + $resourceResult = $departmentResourceGateway->selectBy(['gibbonDepartmentID' => $gibbonDepartmentID, 'type' => 'File'], ['gibbonDepartmentResourceID'])->fetchAll(); + + foreach ($resourceResult as $resource) { + $resourceDeleted = $fileHandler->deleteFile('gibbonDepartmentResource', $resource['gibbonDepartmentResourceID'], 'url'); + } + + $deleted = $departmentResourceGateway->deleteWhere(['gibbonDepartmentID' => $gibbonDepartmentID]); + + $fileDeleted = $fileHandler->deleteFile('gibbonDepartment', $gibbonDepartmentID, 'logo'); + $URLDelete = $URLDelete.'&return=success0'; header("Location: {$URLDelete}"); } diff --git a/modules/School Admin/house_manage_deleteProcess.php b/modules/School Admin/house_manage_deleteProcess.php index 90f51c1d50..2330aec981 100644 --- a/modules/School Admin/house_manage_deleteProcess.php +++ b/modules/School Admin/house_manage_deleteProcess.php @@ -19,6 +19,8 @@ along with this program. If not, see . */ +use Gibbon\Contracts\Filesystem\FileHandler; + include '../../gibbon.php'; $gibbonHouseID = $_POST['gibbonHouseID'] ?? ''; @@ -62,6 +64,8 @@ exit(); } + $fileDeleted = $container->get(FileHandler::class)->deleteFile('gibbonHouse', $gibbonHouseID, 'logo'); + $URLDelete = $URLDelete.'&return=success0'; header("Location: {$URLDelete}"); } diff --git a/modules/Staff/applicationForm_manage_deleteProcess.php b/modules/Staff/applicationForm_manage_deleteProcess.php index 5f5935cf31..be0b57d7ae 100644 --- a/modules/Staff/applicationForm_manage_deleteProcess.php +++ b/modules/Staff/applicationForm_manage_deleteProcess.php @@ -19,6 +19,8 @@ along with this program. If not, see . */ +use Gibbon\Contracts\Filesystem\FileHandler; +use Gibbon\Domain\Staff\StaffApplicationFormFileGateway; use Gibbon\Domain\User\PersonalDocumentGateway; include '../../gibbon.php'; @@ -63,6 +65,13 @@ exit(); } + // Delete file attachments for all staff application form files + $staffAppFiles = $container->get(StaffApplicationFormFileGateway::class)->selectBy(['gibbonStaffApplicationFormID' => $gibbonStaffApplicationFormID], ['gibbonStaffApplicationFormFileID'])->fetchAll(); + + foreach ($staffAppFiles as $staffAppFile) { + $fileDeleted = $container->get(FileHandler::class)->deleteFile('gibbonStaffApplicationFormFile', $staffAppFile['gibbonStaffApplicationFormFileID'], 'path'); + } + //Delete files, but don't return error if it fails $data = array('gibbonStaffApplicationFormID' => $gibbonStaffApplicationFormID); $sql = 'DELETE FROM gibbonStaffApplicationFormFile WHERE gibbonStaffApplicationFormID=:gibbonStaffApplicationFormID'; diff --git a/modules/Staff/coverage_manage_deleteProcess.php b/modules/Staff/coverage_manage_deleteProcess.php index a7a18aacf0..a20307761d 100644 --- a/modules/Staff/coverage_manage_deleteProcess.php +++ b/modules/Staff/coverage_manage_deleteProcess.php @@ -19,6 +19,7 @@ along with this program. If not, see . */ +use Gibbon\Contracts\Filesystem\FileHandler; use Gibbon\Domain\Staff\StaffCoverageGateway; use Gibbon\Domain\Staff\StaffCoverageDateGateway; use Gibbon\Domain\Staff\StaffAbsenceGateway; @@ -61,6 +62,8 @@ // Then delete the coverage itself $partialFail &= !$staffCoverageGateway->delete($gibbonStaffCoverageID); + $fileDeleted = $container->get(FileHandler::class)->deleteFile('gibbonStaffCoverage', $gibbonStaffCoverageID, 'attachmentContent'); + // Check for other coverage linked to this absence $otherCoverage = $staffCoverageGateway->selectBy(['gibbonStaffAbsenceID' => $values['gibbonStaffAbsenceID']])->fetchAll(); diff --git a/modules/Students/applicationForm_manage_deleteProcess.php b/modules/Students/applicationForm_manage_deleteProcess.php index 073363a115..a6a7d248a0 100644 --- a/modules/Students/applicationForm_manage_deleteProcess.php +++ b/modules/Students/applicationForm_manage_deleteProcess.php @@ -19,6 +19,8 @@ along with this program. If not, see . */ +use Gibbon\Contracts\Filesystem\FileHandler; +use Gibbon\Domain\Students\ApplicationFormFileGateway; use Gibbon\Domain\System\LogGateway; use Gibbon\Domain\User\PersonalDocumentGateway; @@ -68,7 +70,7 @@ exit(); } - //Attempt to write logo + //Attempt to write log $logGateway->addLog($session->get('gibbonSchoolYearIDCurrent'), 'Students', $session->get('gibbonPersonID'), 'Application Form - Delete', array('gibbonApplicationFormID' => $gibbonApplicationFormID, 'applicationFormContents' => serialize($row)), $_SERVER['REMOTE_ADDR']); @@ -102,6 +104,19 @@ $personalDocumentGateway->deletePersonalDocuments('gibbonApplicationFormParent1', $gibbonApplicationFormID); $personalDocumentGateway->deletePersonalDocuments('gibbonApplicationFormParent2', $gibbonApplicationFormID); + // Delete file attachments for all application form files + $appFiles = $container->get(ApplicationFormFileGateway::class)->selectBy(['gibbonApplicationFormID' => $gibbonApplicationFormID], ['gibbonApplicationFormFileID'])->fetchAll(); + + foreach ($appFiles as $appFile) { + $fileDeleted = $container->get(FileHandler::class)->deleteFile('gibbonApplicationFormFile', $appFile['gibbonApplicationFormFileID'], 'path'); + } + + //Delete files, but don't return error if it fails + $data = ['gibbonApplicationFormID' => $gibbonApplicationFormID]; + $sql = 'DELETE FROM gibbonApplicationFormFile WHERE gibbonApplicationFormID=:gibbonApplicationFormID'; + $result = $connection2->prepare($sql); + $result->execute($data); + $URLDelete = $URLDelete.'&return=success0'; header("Location: {$URLDelete}"); } diff --git a/modules/Students/medicalForm_manage_condition_deleteProcess.php b/modules/Students/medicalForm_manage_condition_deleteProcess.php index 75fd0812d9..21733ca1fd 100644 --- a/modules/Students/medicalForm_manage_condition_deleteProcess.php +++ b/modules/Students/medicalForm_manage_condition_deleteProcess.php @@ -19,6 +19,8 @@ along with this program. If not, see . */ +use Gibbon\Contracts\Filesystem\FileHandler; + include '../../gibbon.php'; //Check if gibbonPersonMedicalID and gibbonPersonMedicalConditionID specified @@ -67,6 +69,8 @@ exit(); } + $fileDeleted = $container->get(FileHandler::class)->deleteFile('gibbonPersonMedicalCondition', $gibbonPersonMedicalConditionID, 'attachment'); + $URLDelete = $URLDelete.'&return=success0'; header("Location: {$URLDelete}"); } diff --git a/modules/User Admin/user_manage_deleteProcess.php b/modules/User Admin/user_manage_deleteProcess.php index 1f83e5458d..7978cb321f 100644 --- a/modules/User Admin/user_manage_deleteProcess.php +++ b/modules/User Admin/user_manage_deleteProcess.php @@ -19,6 +19,7 @@ along with this program. If not, see . */ +use Gibbon\Contracts\Filesystem\FileHandler; use Gibbon\Domain\User\PersonalDocumentGateway; include '../../gibbon.php'; @@ -67,6 +68,8 @@ // Personal Documents $container->get(PersonalDocumentGateway::class)->deletePersonalDocuments('gibbonPerson', $gibbonPersonID); + $fileDeleted = $container->get(FileHandler::class)->deleteFile('gibbonPerson', $gibbonPersonID, 'image_240'); + $URLDelete = $URLDelete.'&return=success0'; header("Location: {$URLDelete}"); } diff --git a/src/Domain/FormalAssessment/InternalAssessmentEntryGateway.php b/src/Domain/FormalAssessment/InternalAssessmentEntryGateway.php new file mode 100644 index 0000000000..f2fd9d0ace --- /dev/null +++ b/src/Domain/FormalAssessment/InternalAssessmentEntryGateway.php @@ -0,0 +1,41 @@ +. +*/ + +namespace Gibbon\Domain\FormalAssessment; + +use Gibbon\Domain\Traits\TableAware; +use Gibbon\Domain\QueryCriteria; +use Gibbon\Domain\QueryableGateway; + +/** + * @version v31 + * @since v31 + */ +class InternalAssessmentEntryGateway extends QueryableGateway +{ + use TableAware; + + private static $tableName = 'gibbonInternalAssessmentEntry'; + private static $primaryKey = 'gibbonInternalAssessmentEntryID'; + + private static $searchableColumns = []; + +} diff --git a/src/Domain/Staff/StaffApplicationFormFileGateway.php b/src/Domain/Staff/StaffApplicationFormFileGateway.php index 48f8981f22..a7e14ea3b2 100644 --- a/src/Domain/Staff/StaffApplicationFormFileGateway.php +++ b/src/Domain/Staff/StaffApplicationFormFileGateway.php @@ -21,6 +21,8 @@ namespace Gibbon\Domain\Staff; +use Gibbon\Contracts\Database\Connection; +use Gibbon\Contracts\Filesystem\FileHandler; use Gibbon\Domain\QueryCriteria; use Gibbon\Domain\QueryableGateway; use Gibbon\Domain\ScrubbableGateway; @@ -47,4 +49,15 @@ class StaffApplicationFormFileGateway extends QueryableGateway implements Scrubb private static $scrubbableKey = ['timestamp', 'gibbonStaffApplicationForm', 'gibbonStaffApplicationFormID']; private static $scrubbableColumns = ['path' => 'deleteFile']; + + /** + * @var FileHandler + */ + private $fileHandler; + + public function __construct(Connection $db, FileHandler $fileHandler) + { + parent::__construct($db); + $this->fileHandler = $fileHandler; + } } diff --git a/src/Domain/Students/ApplicationFormFileGateway.php b/src/Domain/Students/ApplicationFormFileGateway.php index 9117d850fc..48ea39f605 100644 --- a/src/Domain/Students/ApplicationFormFileGateway.php +++ b/src/Domain/Students/ApplicationFormFileGateway.php @@ -21,6 +21,8 @@ namespace Gibbon\Domain\Students; +use Gibbon\Contracts\Database\Connection; +use Gibbon\Contracts\Filesystem\FileHandler; use Gibbon\Domain\QueryCriteria; use Gibbon\Domain\QueryableGateway; use Gibbon\Domain\ScrubbableGateway; @@ -45,4 +47,15 @@ class ApplicationFormFileGateway extends QueryableGateway implements ScrubbableG private static $scrubbableKey = ['timestamp', 'gibbonApplicationForm', 'gibbonApplicationFormID']; private static $scrubbableColumns = ['path' => 'deleteFile']; + + /** + * @var FileHandler + */ + private $fileHandler; + + public function __construct(Connection $db, FileHandler $fileHandler) + { + parent::__construct($db); + $this->fileHandler = $fileHandler; + } } diff --git a/src/Domain/Students/MedicalConditionGateway.php b/src/Domain/Students/MedicalConditionGateway.php index 4a06b3ccbf..bb6ddce79f 100644 --- a/src/Domain/Students/MedicalConditionGateway.php +++ b/src/Domain/Students/MedicalConditionGateway.php @@ -21,6 +21,8 @@ namespace Gibbon\Domain\Students; +use Gibbon\Contracts\Database\Connection; +use Gibbon\Contracts\Filesystem\FileHandler; use Gibbon\Domain\QueryCriteria; use Gibbon\Domain\QueryableGateway; use Gibbon\Domain\ScrubbableGateway; @@ -45,4 +47,15 @@ class MedicalConditionGateway extends QueryableGateway implements ScrubbableGate private static $scrubbableKey = ['gibbonPersonID', 'gibbonPersonMedical', 'gibbonPersonMedicalID']; private static $scrubbableColumns = ['name' => '','gibbonAlertLevelID'=> null,'triggers' => '','reaction' => '','response' => '','medication' => '','lastEpisode'=> null,'lastEpisodeTreatment' => '','comment' => '','attachment'=> 'deleteFile']; + + /** + * @var FileHandler + */ + private $fileHandler; + + public function __construct(Connection $db, FileHandler $fileHandler) + { + parent::__construct($db); + $this->fileHandler = $fileHandler; + } } diff --git a/src/Domain/Traits/Scrubbable.php b/src/Domain/Traits/Scrubbable.php index 62fbe1529b..e27290d304 100644 --- a/src/Domain/Traits/Scrubbable.php +++ b/src/Domain/Traits/Scrubbable.php @@ -78,16 +78,26 @@ public function scrub(string $cutoffDate, array $context = []) : array }, $columns); // Handle files that need deleted along with the scrub - $absolutePath = $this->db()->selectOne("SELECT value FROM gibbonSetting WHERE scope='System' AND name='absolutePath'"); + $absolutePath = null; foreach ($columns as $name => $property) { if ($property != 'deleteFile') continue; foreach ($scrubbable as $primaryKey => $values) { - $values = $this->getByID($primaryKey, [$name]); $columns[$name] = 'Deleted File'; - if (is_file($absolutePath.'/'.$values[$name])) { - unlink($absolutePath.'/'.$values[$name]); + if (isset($this->fileHandler)) { + // Use FileHandler to clean up gibbonFilePointer, gibbonFile, and the physical file + $this->fileHandler->deleteFile($this->getTableName(), $primaryKey, $name); + } else { + // Fallback: unlink the physical file directly + if ($absolutePath === null) { + $absolutePath = $this->db()->selectOne("SELECT value FROM gibbonSetting WHERE scope='System' AND name='absolutePath'"); + } + $values = $this->getByID($primaryKey, [$name]); + + if (is_file($absolutePath.'/'.$values[$name])) { + unlink($absolutePath.'/'.$values[$name]); + } } } } diff --git a/src/Domain/User/PersonalDocumentGateway.php b/src/Domain/User/PersonalDocumentGateway.php index 0266006662..03c9cffd04 100644 --- a/src/Domain/User/PersonalDocumentGateway.php +++ b/src/Domain/User/PersonalDocumentGateway.php @@ -21,13 +21,14 @@ namespace Gibbon\Domain\User; -use Gibbon\Services\Format; -use Gibbon\Domain\QueryCriteria; +use Gibbon\Contracts\Database\Connection; +use Gibbon\Contracts\Filesystem\FileHandler; use Gibbon\Domain\QueryableGateway; +use Gibbon\Domain\QueryCriteria; use Gibbon\Domain\ScrubbableGateway; use Gibbon\Domain\Traits\Scrubbable; -use Gibbon\Domain\Traits\TableAware; use Gibbon\Domain\Traits\ScrubByTimestamp; +use Gibbon\Domain\Traits\TableAware; /** * @version v22 @@ -47,6 +48,17 @@ class PersonalDocumentGateway extends QueryableGateway implements ScrubbableGate private static $scrubbableKey = 'timestamp'; private static $scrubbableColumns = ['documentNumber' => null,'documentName' => null,'documentType' => null,'dateIssue' => null,'dateExpiry' => null,'filePath' => 'deleteFile','country' => null]; + /** + * @var FileHandler + */ + private $fileHandler; + + public function __construct(Connection $db, FileHandler $fileHandler) + { + parent::__construct($db); + $this->fileHandler = $fileHandler; + } + /** * @param QueryCriteria $criteria * @return DataSet @@ -171,6 +183,15 @@ public function updatePersonalDocumentOwnership($foreignTableOld, $foreignTableO public function deletePersonalDocuments($foreignTable, $foreignTableID) { + // Clean up file pointers before deleting records + $data = ['foreignTable' => $foreignTable, 'foreignTableID' => $foreignTableID]; + $sql = "SELECT gibbonPersonalDocumentID FROM gibbonPersonalDocument WHERE foreignTable=:foreignTable AND foreignTableID=:foreignTableID AND (filePath IS NOT NULL AND filePath != '')"; + $documents = $this->db()->select($sql, $data)->fetchAll(); + + foreach ($documents as $document) { + $this->fileHandler->deleteFile('gibbonPersonalDocument', $document['gibbonPersonalDocumentID'], 'filePath'); + } + $data = ['foreignTable' => $foreignTable, 'foreignTableID' => $foreignTableID]; $sql = "DELETE FROM gibbonPersonalDocument WHERE foreignTable=:foreignTable AND foreignTableID=:foreignTableID"; diff --git a/src/Filesystem/FileHandler.php b/src/Filesystem/FileHandler.php index 620ca9e5ca..4e9270f1f9 100644 --- a/src/Filesystem/FileHandler.php +++ b/src/Filesystem/FileHandler.php @@ -197,7 +197,7 @@ public function deleteFile(string $foreignTable, int|string $foreignTableID, str $this->db->commit(); // Delete physical file only after successful commit (if no other pointers existed) - if ($pointerCount == 0 &&!empty($absolutePath) && file_exists($absolutePath)) { + if ($pointerCount == 0 && !empty($absolutePath) && file_exists($absolutePath)) { unlink($absolutePath); }